-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Add support for LPArray when marshalling struct fields #8719
Comments
@Tragetaschen, could you try explicitly marking The default marshalling for arrays is described here: https://docs.microsoft.com/en-us/dotnet/framework/interop/default-marshaling-for-arrays You will note that under the When marshalling from managed to unmanaged, the size of the array is determined by the managed length. When marshalling from unmanaged to managed, the size of the array is determined by the For P/Invoke methods, there exists a |
With this declaration: public unsafe struct msghdr
{
public IntPtr name;
public NativeInt namelen;
public iovec* iov;
public NativeInt iovlen;
[MarshalAs(UnmanagedType.LPArray)]
public int[] control;
public NativeInt controllen;
public int flags;
} the exception is the same. |
@Tragetaschen I will take a look at why it says "unklnown' , but you can marshal the field as ByValArray.
|
Thanks for looking into it. The C API expects a pointer to the first array element. Wouldn't
|
@Tragetaschen, it looks like some of your types aren't accurate representations of the native side, which might be causing some problems. The native declarations are: #define __STD_TYPE typedef
#define __U32_TYPE unsigned int
__STD_TYPE __U32_TYPE __socklen_t;
typedef __socklen_t socklen_t;
struct iovec
{
void *iov_base; /* Pointer to data. */
size_t iov_len; /* Length of data. */
};
struct msghdr
{
void *msg_name; /* Address to send to/receive from. */
socklen_t msg_namelen; /* Length of address data. */
struct iovec *msg_iov; /* Vector of data to send/receive into. */
size_t msg_iovlen; /* Number of elements in the vector. */
void *msg_control; /* Ancillary data (eg BSD filedesc passing). */
size_t msg_controllen; /* Ancillary data buffer length.
!! The type should be socklen_t but the
definition of the kernel is incompatible
with this. */
int msg_flags; /* Flags on received message. */
};
extern ssize_t recvmsg (int __fd, struct msghdr *__message, int __flags); So I would expect the most accurate representation to be: private static extern IntPtr recvmsg( // You return int, can cause issues for 64-bit
int __fd, // You use IntPtr, can cause issues for 64-bit
ref msghdr __message, //
int __flags //
);
private unsafe struct iovec
{
public void* iov_base; // You use byte*, shouldn't be a problem
public IntPtr iov_len; // You use int, can cause issues for 64-bit
}
private unsafe struct msghdr
{
public void* msg_name; // You use IntPtr, shouldn't be a problem
public uint msg_namelen; // You use int, shouldn't be a problem
public iovec* msg_iov; //
public IntPtr msg_iovlen; // You use int, can cause issues for 64-bit
public void* msg_control; // You use int[], byte[] would be more accurate, I don't think this should cause any problems in either case. If you use an array, you must specify MarshalAs(UnmanagedType.LPArray)
public IntPtr msg_controllen; // You use int, can cause issues for 64-bit -- This is defined in x86_64-linux_gnu\bits\socket.h and is explicitly documented to be different from the POSIX declaration
public int msg_flags; //
} |
@tannergooding I had already refactored the code to split 32- and 64-bit operations. Luckily it's possible to hide those details behind an interface. As mentioned, decorating the |
|
With the manual fixed statement, I'm good. I'll update the title accordingly |
I'm having the same issue. I expected something like: |
+1, looking forward for |
This would save a ton of energy, thanks for looking into it |
@elinor-fung and @jkoritzinsky Let's make sure the struct marshalling for DllImport source generation can handle this case. #46838. |
Now that the LibraryImport generator (i.e., source generated Support for marshalling customized types can be found in the new API described at #66121. |
Today, I have finally found the reason, why my DBus implementation works with Mono, but doesn't with .NET Core:
Here's a quick copy of the code from here
When calling
recvmsg
, Mono is fine with marshalling thecontrol
member ofmsghdr
. For .NET Core (1.1 and 2.0-preview2), I had to changeint[]
toint*
and add another fixed statement to my code.The
Unknown error
makes me wonder if there's something missing in .NET Core.The text was updated successfully, but these errors were encountered: