首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将结构从C#传递到C++ DLL?

如何将结构从C#传递到C++ DLL?
EN

Stack Overflow用户
提问于 2018-05-02 13:47:08
回答 2查看 2.4K关注 0票数 2

好的,我的激光装置控制器的一系列问题继续.我想从我的C++代码中调用DLL中的以下C#函数:

代码语言:javascript
运行
复制
extern "C" _declspec(dllimport) int SendFrame(DWORD deviceIndex, byte* pData, DWORD numOfPoints, DWORD scanrate);

指针pData指向在C++头文件中定义的激光点数组,如下所示:

代码语言:javascript
运行
复制
#pragma pack (1)
struct LaserPoint {
    WORD x;
    WORD y;
    byte colors[6];
};

在C#方面,我将函数导入定义如下:

代码语言:javascript
运行
复制
[DllImport("..\\..\\dll\\StclDevices.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int SendFrame(UInt32 deviceIndex, ref byte[] pData, UInt32 numOfPoints, UInt32 scanrate);

..。LaserPoint结构是这样的:

代码语言:javascript
运行
复制
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct LaserPoint {
    public UInt16 x;
    public UInt16 y;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
    public byte[] colors;
}

然后,我像这样调用SendFrame函数:

代码语言:javascript
运行
复制
LaserPoint point = new LaserPoint();
point.x = 16384;
point.y = 32768;
point.colors = new byte[] {255, 0, 0, 0, 0, 0};

byte[] arr = point2array(points);
SendFrame(0, ref arr, 1, 30000);

这是我的函数,用于将LaserPoint结构实例转换为字节数组:

代码语言:javascript
运行
复制
private static byte[] point2array(object obj) {
    int len = Marshal.SizeOf(obj);
    byte[] arr = new byte[len];
    IntPtr ptr = Marshal.AllocHGlobal(len);
    Marshal.StructureToPtr(obj, ptr, true);
    Marshal.Copy(ptr, arr, 0, len);
    Marshal.FreeHGlobal(ptr);
    return arr;
}

但我的激光装置没有收到正确的输入,因为激光的行为非常奇怪。在C++项目中使用相同的代码很好。因此,这个bug就存在于这个C#互操作性代码的某个地方。

有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-02 13:53:37

数组已经是引用类型,因此ref byte[]是一个双间接方向,类似于byte** -丢失ref

票数 3
EN

Stack Overflow用户

发布于 2018-05-02 14:30:46

如果只打算在这里使用LaserPoint结构,则可以将函数定义为

代码语言:javascript
运行
复制
[DllImport("..\\..\\dll\\StclDevices.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int SendFrame(UInt32 deviceIndex, LaserPoint[] pData, UInt32 numOfPoints, UInt32 scanrate);

并摆脱复制,让运行时为您做这件事。

否则,正如ildjarn所说,摆脱ref应该有效,因为字节数组已经是引用(指针)类型。

关于如何做这些事情的例子,PInvoke维基已经为大多数的windows提供了结构和签名,所以虽然您的调用不会出现,但是也有很多类似的例子。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50136242

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档