- INDEX VB TO NET
- KNOWLEDGE BASE
- EWIS- NOTES
- WARNING #8007
WARNING #8007
Trying to marshal a non Bittable Type (%1). A special conversion might be required at this point. Moreover use the 'External Marshalling attributes for Structs' feature enabled if required.
This message indicates that at least one of the arguments to an API call that has now been converted to a .NET Platform invoke call has an issue.
One important thing to note is the concept of “Bittable Types”.
Most data types have a common representation in both managed and unmanaged memory and do not require special handling by the interop marshaler. These types are called blittable types because they do not require conversion when passed between managed and unmanaged code.
The following types from the System namespace are blittable types:
- System.Byte
- System.SByte
- System.Int16
- System.UInt16
- System.Int32
- System.UInt32
- System.Int64
- System.IntPtr
- System.UIntPtr
The following complex types are also blittable types:
- One-dimensional arrays of blittable types, such as an array of integers.
- Formatted value types that contain only blittable types (and classes if they are marshaled as formatted types).
This is important for VB6 migrations because if you are calling that a DLL you won’t be able to pass a NON-Bittable type because that DLL will expect a binary representation different from that in the .NET virtual machine.
This is also an issue in other scenarios like:
- Serializing content to files
- Sending messages through messaging mechanisms like named-pipes or sockets.
This is also very important for Struct Marshalling. The VBUC helps you a lot in this matter.
What to do with non-bittable types?
If your type is not bittable and it is a structs the VBUC can automatically add marshalling attributes that will help you.
If your type is a decimal, a datatime or an guid you can use some helper instead. For example the helpers by Andrey Akinshing
So for example for Decimal you can use:
namespace BlittableStructs { public struct BlittableDecimal { private long longValue; public BlittableDecimal(decimal value) { longValue = decimal.ToOACurrency(value); } public decimal Value { get { return decimal.FromOACurrency(longValue); } set { longValue = decimal.ToOACurrency(value); } } public static explicit operator BlittableDecimal(decimal value) { return new BlittableDecimal { Value = value }; } public static implicit operator decimal (BlittableDecimal value) { return value.Value; } } }
Or for DateTime you can use
using System; namespace BlittableStructs { public struct BlittableDateTime { private long ticks; public BlittableDateTime(DateTime dateTime) { ticks = dateTime.Ticks; } public DateTime Value { get { return new DateTime(ticks); } set { ticks = value.Ticks; } } public static explicit operator BlittableDateTime(DateTime value) { return new BlittableDateTime { Value = value }; } public static implicit operator DateTime(BlittableDateTime value) { return value.Value; } } }