C++ 定义
typedef struct Stu
{
public:
int Age;
char Name[20];
};
typedef struct Num
{
int N1;
int N2;
};
extern "C" __declspec(dllexport) void FindInfo(Stu& stu)
{
stu.Age = 10;
strcpy_s(stu.Name, "徐滔");
}
extern "C" __declspec(dllexport) int Add(int a,int b)
{
return a + b;
}
extern "C" __declspec(dllexport) int GetNumSum(Num* num)
{
return num->N1 + num->N2;
}
extern "C" __declspec(dllexport) bool InputInfo(int age,char name[20], Stu* stuInfo)
{
stuInfo->Age = age;
char* test = name;
strcpy_s(stuInfo->Name, name);
return true;
}
在C# 中需要重新定义结构
[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public struct Stu
{
public int Age;
[System.Runtime.InteropServices.MarshalAs(UnmanagedType.ByValTStr,SizeConst =20)]
public string Name;
}
注意c# 中 和c++ 中的数据类型的对应。
public struct Num
{
public int N1;
public int N2;
}
申明 调用函数
[DllImport("MyFuncDll.dll", EntryPoint = "FindInfo", CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Unicode)]
extern static void FindInfo(ref Stu stu);
[DllImport("MyFuncDll.dll", EntryPoint = "Add", CallingConvention = CallingConvention.Cdecl)]
public extern static int Add(int a, int b);
[DllImport("MyFuncDll.dll", EntryPoint = "GetNumSum", CallingConvention = CallingConvention.Cdecl)]
public extern static int GetNumSum(ref Num num);
[DllImport("MyFuncDll.dll", EntryPoint = "InputInfo", CallingConvention = CallingConvention.Cdecl,
CharSet =CharSet.Ansi)]
特别要注意 CharSet 属性的设置。
调用测试
int re = Add(1, 3);
Num n = new Num() { N1 = 1, N2 = 2 };
int r = GetNumSum(ref n);
Stu stu = new UseCppDll.Stu();
FindInfo(ref stu);
MessageBox.Show(stu.Name);
在c#中调用C++传递 char[]类型的参数
string sna = "系统";
bool b = InputInfo(23, sna, ref stuInfo);
//-------------------------------------------------------------
C# 调用 C++ dll返回字符串问题
做个简单的例子,将传入的字符串复制后再返回…
C++中定义方法:
EXTERN_C __declspec(dllexport) bool TryCopyStr(char* src, char** desstr)
{
_memccpy(*desstr, src,0, strlen(src));
return true;
}
参数: src —源字符串
参数:desstr—目标字符串(也就是要将返回值赋给该参数),注意其类型为 char**
C# 代码:
//dll调用申明
[DllImport("dotNetCppStrTest.dll", EntryPoint = "TryCopyStr", CallingConvention = CallingConvention.Cdecl)]
public extern static bool TryCopyStr(string src,ref StringBuilder desStr);
//测试方法
private void TestTryGetStr()
{
bool suc = false;
StringBuilder resultStrBuilder = new StringBuilder();
string srcStr = "this is string from .net 从.net传过去的字符串";
suc = TryCopyStr(srcStr,ref resultStrBuilder);
}
注:
参数 desStr 是 StringBuilder 类型,而不是 String 类型。因为在dll中对该参数进行了重新赋值,也即是参数值发生了改变,String 类型的值是不能改变的。
此方法在VS2015测试通过。