如何使用unsigned char *将结构从C#传递到C ++? [英] How to pass struct with unsigned char* from C# to C++?

查看:1063
本文介绍了如何使用unsigned char *将结构从C#传递到C ++?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些结构描述和一些方法的 C ++ dll

  struct MSG_STRUCT {
unsigned long dataSize;
unsigned char * data;
}

并且功能例如:


$ b b

  unsigned long ReadMsg(unsigned long msgId,MSG_STRUCT * readMsg)
{
readMsg-> dataSize = someDataSize;
readMsg-> data = someData;
}

所以我想从 C#

  [StructLayout(LayoutKind.Sequential)] 
struct MSG_STRUCT
{
UInt32 dataSize ;
byte [] data;
}

[DllImport(mydll.dll)]
public static Int32 ReadMsg(UInt32 msgId,ref MSG_STRUCT readMsg);

所以我试图调用 C#函数:

  var readMsg = new MSG_STRUCT(); 
readMsg.data = new byte [4128];
Int32 res = ReadMsg(someMsgId,ref readMsg);

但我没有得到数据正常。
我也尝试使用 IntPrt 类型参数调用 ReadMsg ,但 Marshal。 PtrToStructure 有时给我 AccessViolationException



我没有任何想法如何将 MSG_STRUCT 的指针从 C#传递到 C ++ ,并接收填充 MSG_STRUCT的结果。数据



最终解决方案对我有用:
我使用xanatos提供的解决方案的一部分:
我为我的DllImport函数设置 CallingConvention = CallingConvention.Cdecl
我发现我还需要更改:

  [MarshalAs(UnmanagedType.ByValArray,SizeConst = 4128) 
public byte [] Data;感谢大家的帮助

你可以尝试:

  [StructLayout(LayoutKind。 Sequential)] 
public struct MSG_STRUCT
{
int dataSize;
IntPtr数据;

public byte [] GetData()
{
var bytes = new byte [dataSize];
Marshal.Copy(data,bytes,0,dataSize);
return bytes;
}
}

[DllImport(NativeLibrary.dll,CallingConvention = CallingConvention.Cdecl)]
public static extern uint ReadMsg(uint msgId,ref MSG_STRUCT readMsg );

,然后:

  MSG_STRUCT msg = new MSG_STRUCT(); 
uint res = ReadMsg(123,ref msg);
byte [] bytes = msg.GetData();

您的C函数重新分配数据指针,所以你必须把它回到C#。最简单的方法(对我来说)是简单地传递 IntPtr 并做一些明确的 Marshal.Copy(...)



另一种方法是使用 data a byte [] ,但是在C端你必须 memcpy(readMsg-> data,someData,someDataSize),而不是简单地赋值 readMsg- > data = someData


I have some C++ dll with struct description and some methods:

struct MSG_STRUCT {  
    unsigned long dataSize;
    unsigned char* data;
}

And function for example:

unsigned long ReadMsg( unsigned long msgId, MSG_STRUCT* readMsg)
{
    readMsg->dataSize = someDataSize;
    readMsg->data = someData;
}

So I want to call this function from C#:

[StructLayout(LayoutKind.Sequential)]
struct MSG_STRUCT 
{
    UInt32 dataSize;
    byte[] data;
}

[DllImport("mydll.dll")]
public static Int32 ReadMsg( UInt32 msgId, ref MSG_STRUCT readMsg);

So I tried to call C# function like:

var readMsg = new MSG_STRUCT();
readMsg.data = new byte[4128];
Int32 res = ReadMsg( someMsgId, ref readMsg);

But I didn't get smth normal in data. I also tried to call ReadMsg with IntPrt type parameter, but Marshal.PtrToStructure gave me AccessViolationException sometimes.

I don't have any ideas how to pass a pointer to MSG_STRUCT from C# to C++ and receive the result as filled MSG_STRUCT.data

The final solutionthat worked for me: I used a part of solution offered by xanatos: I set CallingConvention = CallingConvention.Cdecl for my DllImport function. I found out that I also need to change:

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4128)]
public byte[] Data;

Thanks everyone for your help

解决方案

You could try with:

[StructLayout(LayoutKind.Sequential)]
public struct MSG_STRUCT 
{
    int dataSize;
    IntPtr data;

    public byte[] GetData() 
    {
        var bytes = new byte[dataSize];
        Marshal.Copy(data, bytes, 0, dataSize);
        return bytes;
    }
}

[DllImport("NativeLibrary.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern uint ReadMsg(uint msgId, ref MSG_STRUCT readMsg);

and then:

MSG_STRUCT msg = new MSG_STRUCT();
uint res = ReadMsg(123, ref msg);
byte[] bytes = msg.GetData();

Your C function is reassigning the data pointer, so you have to marshal it back to C#. The easiest way (for me) is to simply pass a IntPtr and do some explicit Marshal.Copy(...).

An alternative is to have data a byte[], but then in C-side you have to memcpy(readMsg->data, someData, someDataSize) instead of simply assigning readMsg->data = someData.

这篇关于如何使用unsigned char *将结构从C#传递到C ++?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆