C#调用C++的DLL,通过参数返回数据。

首先需要把对应的函数开放出来,使用如下的宏:

#ifdef EXPORTDLL_EXPORTS
#define EXPORTDLL extern "C" __declspec(dllexport)
#else
#define EXPORTDLLextern "C" __declspec(dllimport)
#endif

通过参数返回数据,在C++中通过引用变量来实现(实测通过C++调用C++的DLL,并不需要引用,即不需要&,但是C#调用就需要,为什么?),如

EXPORTDLL int test(char* &url, char* &type, char* &add)

在C#中引用时,通过ref来返回数据。C++中的char*,在C#中可以用指针IntPtr来对应,也可以用StringBuilder,用指针时,需要给指针初始化并给予足够的大小,用StringBuilder时,只要new StringBuilder()就可以,在C++中会自动分配 。实测需要分配给足够的大小,否则程序会偶尔出错。

用指针如下:

[DllImport("test.dll", EntryPoint = "test", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int test(ref IntPtr url,ref IntPtr type,ref IntPtr add);

通过以下方法取对应的字符串:

Marshal.PtrToStringAnsi(a1)

用StringBuilder如下:

public static extern int test(ref StringBuilder url,ref StringBuilder type,ref StringBuilder add);
StringBuilder url=new StringBuilder();

取值就很方便了。建议用StringBuilder 。

由于水平问题,在实际调试中,C++函数中能给参数赋值,但是跳出后变量值就清空了,原因是内存已经释放,所以在C++给返回变量赋值的时候,一定要用复制,不能直接**赋值 **。在此做记录,以免忘记。

strcpy(url, u2.c_str());
strcpy(type, t2.c_str());
strcpy(add, a2.c_str());

也可以用

_snprintf_s

通过这样的复制,就把实际的值复制给对应的参数所指的内存了。函数结束时这些内存并不会被释放。在C#中,

顺便记录下,C++返回结构体,在C#中的调用
C++中结构体:

struct teststruct{
	struct teststruct* pNext;
	char* url;
	char* st;
	char buffer[2];
};

C#中也要先对应一个结构体如下:

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct teststruct
    {
        public IntPtr pNext;//teststruct结构体引用的自身,链表        
        public IntPtr url;
        public IntPtr st;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] buffer;
    }

C++中函数

EXPORTDLL struct teststruct test()

C#中调用

[DllImport("test.dll", EntryPoint = "test", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern UPNPreturn Set_UPNP();

具体调用:

IntPtr struct1= Marshal.AllocHGlobal(1024);
struct1= test();
StringBuilder ss = new StringBuilder();
while (struct1!= null && struct1.ToInt32() > 0)
{
	teststruct struct2= (teststruct)Marshal.PtrToStructure(struct1, typeof(teststruct));
	ss.Append(string.Format("url:{0},st:{1}", Marshal.PtrToStringAnsi(struct2.url),
		Marshal.PtrToStringAnsi(struct2.st)) + "\r\n");
	struct1= struct2.pNext;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值