-
-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
System.Runtime.InteropServices.MarshalDirectiveException: Cannot marshal 'parameter #1': Non-blittable generic types cannot be marshaled #99
Comments
@Nihlus I've resolved this problem by just switching back to normal |
This may be due to how ADL marshals (or rather, doesn't marshal) spans under the hood - spans weren't widely adopted when I last fiddled with the code, and it's probably a feature gap right now. I'll see what I can do, though. |
One option is to declare the parameter as a |
@Nihlus Definitely isn't something I considered (or even knew about). The crashing problem appears to be due to something modifying memory that it shouldn't -- on Windows I get an access violation exception and on Linux I just get a crash. It oddly appears to be a function that (I don't think) modifies its parameter. I might need to ask the library author about that though. Changing that to a |
@ethindp I've gone through the code, and spans are actually marshalled - they get converted into a pinned reference and then into a pointer. If they don't work for you, there's probably something else at play. Can you share the code at issue? |
@Nihlus Sure! Here are the files in question:
This doesn't properly compile right now; for some reason, Roslynn dislikes this line (within the public Span<byte>? userdata; Oddly, it likes it if I change it to: public Memory<byte>? userdata; Also, if you could, I would appreciate it if you could check my unions (those annotated with [StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct AutomationCommandParameters
{
[FieldOffset(0)]
public AutomationAppendPropertyCommand AppendToProperty;
[FieldOffset(sizeof(AutomationAppendPropertyCommand))]
public AutomationClearPropertyCommand ClearProperty;
[FieldOffset(sizeof(AutomationAppendPropertyCommand) + sizeof(AutomationClearPropertyCommand))]
public AutomationSendUserEventCommand SendUserEvent;
} But I don't know if this will actually work or if I need to subtract |
Looking at your code, there are several mismatches between the C# side and the native side. Overall tips:
|
@Nihlus Thank you! I've been working on changing the types to conform closer to the C spec, and thus far I've made some good progress and taken into account your suggestions. As an example, for the return types where C's |
I would use raw pointers for struct members, and then have a higher-level managed layer that wraps it in a nicer type for C# consumption. |
@Nihlus I mean, I could use |
@Nihlus I have a C API that has a lot of
void*
pointers. It also uses callbacks in certain places. Pretty much all of thevoid*
parameters are nullable. But the API also accepts arbitraryfloat*
and other typed arrays, with a separate length parameter. However, I want to useSpan<T>
andMemory<T>
instead of raw arrays if at all possible. However, whenever I try to activate the interface, I get this error:I'm confused because according to many resources that I've found, including the MS docs themselves, they imply that
Span<T>
andMemory<T>
should be able to be passed to unmanaged code or across the FFI boundary. However, this doesn't appear to be the case. (In many places, I'm doing things likeMemory<byte>?
andSpan<byte>?
to indicate that these can be null.) Am I misusing these types? And, if so, how do I use them properly? Should I just revert to normal arrays?The text was updated successfully, but these errors were encountered: