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
    评论
在C++和C#中,结构体是一种用户自定义的数据类型,可以包含多个不同类型的成员变量。在函数调用中,通过传递结构体指针作为参数,可以实现对结构体的修改。 在C++中,可以通过使用指针作为函数参数来传递结构体。示例代码如下: ```cpp #include <iostream> struct MyStruct { int num; char ch; }; void ModifyStruct(MyStruct* ptr) { ptr->num = 10; ptr->ch = 'A'; } int main() { MyStruct myStruct; ModifyStruct(&myStruct); std::cout << "Modified struct: " << myStruct.num << ", " << myStruct.ch << std::endl; return 0; } ``` 在上述代码中,定义了一个名为`MyStruct`的结构体,在`ModifyStruct`函数中,通过传递结构体指针`ptr`,可以直接修改结构体的成员变量。 在C#中,结构体是值类型,传递结构体参数时会进行值拷贝。为了实现类似于C++中的指针参数传递,可以使用`ref`关键字。示例代码如下: ```csharp using System; struct MyStruct { public int num; public char ch; } class Program { static void ModifyStruct(ref MyStruct myStruct) { myStruct.num = 10; myStruct.ch = 'A'; } static void Main(string[] args) { MyStruct myStruct; ModifyStruct(ref myStruct); Console.WriteLine("Modified struct: {0}, {1}", myStruct.num, myStruct.ch); } } ``` 在上述代码中,通过`ref`关键字将结构体参数传递给`ModifyStruct`函数,可以直接修改结构体的成员变量。 总结来说,C++和C#都支持通过结构体指针参数传递来修改结构体的值。在C++中,可以直接使用指针作为参数;而在C#中,需要使用`ref`关键字来实现类似的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值