简单写一个C函数供C#代码调用
在C#中调用C++动态库导出的函数时,有时候需要封送一些复杂的数据结构,这时候不确定自己封送的数据的内存布局对不对,就想要弄个简单的C++项目模拟一下被调用的接口,检查一下C#的数据封送是否正确。因为对C++项目基本上没任何了解,捣鼓了半天才搞定,所以这里简单记录一下过程,以加深记忆。
1. 首先用C++的动态链接库模板创建一个项目。然后在dllmain.cpp中定义一个名为PostMsg的C导出函数,该函数接收MsgData结构体并打印,代码如下:
typedef struct MsgData
{
int index;
char msg;
BYTE data;
} MsgData;
static void dumpData(const MsgData* msg)
{
for (size_t i = 0; i < sizeof(msg->data); i++)
{
printf("%02x ", *(msg->data + i));
if ((i + 1) % 8 == 0)
{
printf("\n");
}
}
}
extern "C"
__declspec(dllexport) void PostMsg(MsgData* msg)
{
printf("index=%d\nmsg=\"%s\"\n", msg->index, msg->msg);
dumpData(msg);
}
2. 然后创建一个C#的控制台程序来调用它。这里通过DllImport特性来导入C++项目的PostMsg函数,同样也定义了对应的MsgData结构体,代码如下:
var msg = new Msg.MsgData()
{
Index = 2025,
Msg = "custom msg",
Data =
};
var ptr = Marshal.AllocHGlobal(Marshal.SizeOf<Msg.MsgData>());
Marshal.StructureToPtr(msg, ptr, false);
Msg.PostMsg(ptr);
internal class Msg
{
public static extern void PostMsg(IntPtr msg);
public struct MsgData
{
public int Index;
public string Msg;
public byte[] Data;
}
}
3. 接着将C++项目添加为C#项目的项目引用。
这里存在一个问题,C#项目不支持添加C++的项目引用,所以这里标了黄色感叹号,虽然构建C#项目的时候会先构建C++项目,但不会自动把C++项目的输出拷贝到C#项目的输出目录。
网上有很多方法能够解决把C++输出拷贝到C#输出目录的问题,我这里采用添加项目文件的方式,在C#的项目文件里添加以下内容:
<ItemGroup>
<None Include="../x64/$(Configuration)/*.dll;../x64/$(Configuration)/*.pdb">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
4. 最后看一下结果:
index=2025
msg="custom msg"
01 02 03 04 05 06 07 08结果正常,这样就可以简单验证一下自己往C函数里封送的数据是不是正确了
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]