编组c++结构到c#
本文关键字:结构 c++ 编组 | 更新日期: 2023-09-27 18:02:27
我在非托管c++中有这样一个简单的结构:
struct Cam
{
char ip[16];
char login[16];
char pass[16];
char name[16];
};
和c#编组结构:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public 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;
}
当我通过函数
将c#结构传递给c++库时[DllImport("NVRLib.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void AddCameraStruct(Cam cam);
...
Cam cam = new Cam();
cam.ip = "192.168.0.232";
cam.login = "admin";
cam.pass = "admin";
cam.name = "kekekeke";
AddCameraStruct(cam);
和c++中传递的值:
__declspec(dllexport) void AddCameraStruct(Camera cam)
{
printf(cam.ip);
printf("'n");
printf(cam.login);
printf("'n");
printf(cam.name);
printf("'n");
printf(cam.pass);
strcpy(camera[CAM_NUM].ip, cam.ip);
strcpy(camera[CAM_NUM].login, cam.login);
strcpy(camera[CAM_NUM].pass, cam.pass);
strcpy(camera[CAM_NUM].name, cam.name);
CAM_NUM++;
}
它打印:
232
<EMPTY LINE>
192.168.0.232
n
我做错了什么?
我从你的评论中了解了更多,
改变__declspec(dllexport) void AddCameraStruct(Camera cam)
__declspec(dllexport) void AddCameraStruct(Cam cam)
更新:你写的:
你是对的,我错过了,IDE没有建议我什么,因为我也有相机类在c++..谢谢你:)
,我认为这是一个复制粘贴错误。在下面的例子中,它已经像这样被纠正了,它可以工作。不确定为什么/如果你的代码包含Cam
收到错误,因为它不是一个可识别的结构(至少在我的环境中)。
底线:你所展示的代码部分是有效的。您使用UnmanagedType.ByValTStr
,这取决于所选择的字符集,您将其定义为CharSet = CharSet.Ansi
,它反过来映射到DLL库中的char *
。这就是它应该被封送的方式,这是完全正确的。
我创建了一个测试应用程序PInvokeTestDll,如下:
DLL部分,在Win32本地DLL项目中:
#include <atlbase.h>
WIN32_DLL_UNMANGLED_API void AddCameraStruct(Camera cam)
{
USES_CONVERSION;
OutputDebugString(A2W(cam.ip));
OutputDebugString(A2W(cam.login));
OutputDebugString(A2W(cam.name));
OutputDebugString(A2W(cam.pass));
}
头文件:
#define WIN32_DLL_UNMANGLED_API extern "C" _declspec(dllexport)
struct Camera
{
char ip[16];
char login[16];
char pass[16];
char name[16];
};
WIN32_DLL_UNMANGLED_API void AddCameraStruct(Camera cam);
c#项目中:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public 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;
}
class Program
{
[DllImport(@"PInvokeTestDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void AddCameraStruct(Cam cam);
static void Main(string[] args)
{
Cam cam = new Cam
{
ip = "192.168.0.232",
login = "admin",
pass = "admin",
name = "kekekeke"
};
AddCameraStruct(cam);
}
}
在Visual Studio的Output> Debug窗口中运行此项目将显示以下内容:
192.168.0.232adminkekekekeadmin
您可以看到,我将Cam
结构重命名为Camera
结构,假设这是您这边的剪切和粘贴错误。我还删除了printf
语句,因为在调试期间看不到输出(OutputDebugString需要LPCWSTR
,因此需要ATL宏A2W
)。
我的猜测是,你没有显示的部分,实际上导致你的结构失败。我假设它是在c++端,因为如果结构是您键入的,它"简单地工作"(这也是通过在调试期间进入DLL函数期间将鼠标悬停在结构的字段上来"证明"的)。我建议您通过做我所做的事情来隔离问题:创建一个只处理封送和DLL导出函数原型的测试项目。