C# C++的数据传递

1. C++ 与 C# 共享同一个int对象:(可推广至一般类型对象)

C#中的函数参数声明与使用传参时增加ref标识符,对应C++的函数参数声明时加上&引用符号;

//C#   
[DllImport("MyDll",CallingConvention = CallingConvention.Cdecl)]
private static extern bool Function1(ref int _num);

int in_num=10;            //声明输入的int变量
int out_num=0;            //声明输出的int变量
Function1(ref in_num);    //传入变量 进入C++ dll中处理 并传出
out_num=in_num;           //in_num传出时,已经改变

//C++
extern "C" __declspec(dllexport) bool Function1(int &_num)
{
    _num=_num++;         //将传入的_num改变并且传出
}

2. C++与C#共享一个double数组(可推广至除了字符串类型的一般类型数组)

就像正常传递一个数组一样,但是C#中需要提前声明好空间;

//C#
[DllImport("MyDll",CallingConvention = CallingConvention.Cdecl)]
private static extern bool Function2(double[] _nums);

double[]  in_nums = new double[256];   //声明传入的in_num数集,预先分配空间
double[]  out_nums = new double[256];  //声明传出的out_nums数集,预先分配空间
Function2(in_nums);                    //传入处理,并传出;
out_nums =in_nums ;                    //in_nums传出时已经改变


//C++
extern "C" __declspec(dllexport) bool Function2(double in_nums[])
//或者声明double* _pointsway一个道理,是完全一样的
{
    double numone=1.0;
    in_nums[0]=numone; //正常的使用即可,但是别超过C#中声明的空间
}

 

3. C++与C#传递字符串

很奇怪,使用类似于double数组的方法传递C#的string或者char[]都无法修改里面的值,但是C++确实是可以接收到数据,只是如果做出了修改,C#无法收到;

想要传入C++ dll的字符串还可以传回来,C#的函数字符串参数要声明成StringBuilder类型;

/*只传进C++中处理,而不用传出,C#函数声明参数为string型,C++函数声明参数为
char[]型即可*/
//C#
[DllImport("PlayWithC4Plus", CallingConvention = CallingConvention.Cdecl)]
private static extern bool Function3(string _str);

string str = "hello";
Function3(str);
Console.WriteLine(str);            //输出依旧是hello,C++中的改变没有传回来

//C++
#define _CRT_SECURE_NO_WARNINGS    //使用strcpy要加上这个
#include <iostream>
using namespace std;
extern "C" __declspec(dllexport) bool Function3(char _str[])
//或者声明double* _pointsway一个道理,是完全一样的
{
	cout << _str<<endl;          //输出hello,证明确实可以传入 
   char* str = "hello you";
	strcpy(_str, str );          //改变_str的值
	cout << _str << endl;        //输出hello you,C++中的_str确实发生了改变
	return true;
}



/*如果想将字符串传进C++,并且C#还可以接收到修改后的值,那就要在C#的函数声明以及参数
传入时使用StringBuilder类型代替string类型*/
//C#
[DllImport("PlayWithC4Plus", CallingConvention = CallingConvention.Cdecl)]
private static extern bool Function4(StringBuilder _str);

 string str = "hello";
 StringBuilder abuf = new StringBuilder(str);
abuf.Capacity = 100;    //设置字符串最大长度
Function4(abuf);        
Console.WriteLine(abuf); //区别来了,abuf的值被修改,证明方法可行。

//C++    与上种只传入不传出的C++代码完全一致
#define _CRT_SECURE_NO_WARNINGS    //使用strcpy要加上这个
#include <iostream>
using namespace std;
extern "C" __declspec(dllexport) bool Function3(char _str[])
//或者声明double* _pointsway一个道理,是完全一样的
{
	cout << _str<<endl;          //输出hello,证明确实可以传入 
   char* str = "hello you";
	strcpy(_str, str );          //改变_str的值
	cout << _str << endl;        //输出hello you,C++中的_str确实发生了改变
	return true;
}

4. C++的dll应该放在什么地方才能被C#程序找到?

应该放在C#工程的exe所在目录,因为从原理上讲,C#会编译成exe,然后运行的时候寻找dll处理外部函数。

 

5. [DllImport("PlayWithC4Plus", CallingConvention = CallingConvention.Cdecl)]

此语句的后一句是说使用C调用约定(即用__cdecl关键字说明)。如果不加上这句可能会出现以下错误:

函数调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值