c# - 如何将结构传递给 C++ 函数并通过一些修改返回相同的结构?

标签 c# c++ .net pinvoke

我的 C++ 函数中有以下结构。

struct Cam
{
    char ip[16];
    char login[16];
    char pass[16];
    char name[16];
};

以下是我从我的 cpp 类中公开的方法-

extern "C" __declspec(dllexport) Cam* AddCameraStruct1(Cam cam)
{
//modify the cam object
}

下面是我在 C# 中定义结构和函数的方式。

[StructLayout(LayoutKind.Sequential)]
    internal unsafe struct Cam
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
        public string ip;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
        public string login;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
        public string pass;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
        public string name;
    }

 [DllImport(@"mydll.dll", CallingConvention = CallingConvention.Cdecl)]
    [return: MarshalAs(UnmanagedType.LPStruct)]
    internal static extern IntPtr AddCameraStruct1(DPAPI.Cam*);

我不知道如何在 c# 中使用它。如果有问题请提出建议。

unsafe
 {
                DPAPI.Cam cam = new DPAPI.Cam();
                cam.ip = "192.168.0.232";
                cam.login = "admin";
                cam.pass = "admin";
                cam.name = "kekekeke";
                DPAPI.Cam* cam1 = (DPAPI.Cam*)DPAPI.AddCameraStruct1(cam);
}

我收到以下错误 -

指针和固定大小的缓冲区只能在不安全的上下文中使用

不能获取托管类型的地址、大小或声明指向托管类型的指针

最佳答案

您不能像您那样从函数返回结构,您可以简单地通过引用传递结构(顺便说一句,这就是整个 Windows API 的定义方式)。

这里是声明结构的方法,不要忘记指明字符集是 Ansi:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal struct Cam
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string ip;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string login;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string pass;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string name;
}

这里是声明方法的方法(ref 参数就像使用 *):

[DllImport(@"mydll.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern void AddCameraStruct1(ref Cam pcam);

以下是如何在 C/C++ 中声明它:

extern "C" __declspec(dllexport) void AddCameraStruct1(Cam *pcam)
{
  strcpy_s(pcam->name, "hello"); // for example
}

现在您可以这样调用它:

var cam = new Cam();
cam.ip = "192.168.0.232";
cam.login = "admin";
cam.pass = "admin";
cam.name = "kekekeke";
AddCameraStruct1(ref cam);
// cam.name is now "hello"

请注意,您根本不需要在代码中使用 unsafe 关键字。

关于c# - 如何将结构传递给 C++ 函数并通过一些修改返回相同的结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44193390/

相关文章:

c# - 将按键事件绑定(bind)到 WPF 中的 ListViewItem

c# - PHP 中的 SQL 更新

c++ - OpenCV highgui220.dll 丢失

c# - Windows azure应用程序开发步骤失败

c# - 使用NEST显示 Elasticsearch 命中值

c# - 自定义用户控件 - 如何添加类型为 Dictionary<int, Color> 的代码集合编辑器

c++ - 查找整数数组中的一对元素,使得 abs(v[i]-v[j]) 最小化

c++ - g++ __thread = 非平凡的构造函数

c# - Entity Framework 中的 "The data reader has more than one field"错误

.net - GDI+实际上还是 "usable"技术吗?