首先c++的代码为:
extern "C" __declspec(dllexport) int add(int x, int y);
extern "C" __declspec(dllexport) int OneArrayOutMemory(int* arrays, int length);
extern "C" __declspec(dllexport) int OneArrayInMemory(int* &arrays, int &length);
extern "C" __declspec(dllexport) int OneArrayInMemoryFree(int*& arrays);
extern "C" __declspec(dllexport) int TwoArrayOutMemory(int* &arrays, int first_length,int second_length);
extern "C" __declspec(dllexport) int TwoArrayInMemory(int** &arrays, int &first_length,int &second_length);
extern "C" __declspec(dllexport) int TwoArrayInMemoryFree(int**& arrays,int first_length);
//实现:
int add(int a, int b)
{
return a + b;
}
extern "C" __declspec(dllexport) int OneArrayOutMemory(int* arrays, int length)
{
for (int i = 0; i < length; ++i)
{
arrays[i] = i + 1;
}
return 0;
}
extern "C" __declspec(dllexport) int OneArrayInMemory(int* &arrays, int& length)
{
length = 10;
arrays = new int[length];
for (int i = 0; i < length; ++i)
{
arrays[i] = i + 1;
}
return 0;
}
extern "C" __declspec(dllexport) int OneArrayInMemoryFree(int*& arrays)
{
if (arrays != nullptr)
{
delete arrays;
arrays = nullptr;
}
return 0;
}
extern "C" __declspec(dllexport) int TwoArrayOutMemory(int* &arrays, int first_length, int second_length)
{
for (int i = 0; i < first_length; ++i)
{
for (int j = 0; j < second_length; ++j)
{
arrays[first_length*i+j] = i * 10 + j + 1;
}
}
return 0;
}
extern "C" __declspec(dllexport) int TwoArrayInMemory(int** &arrays, int& first_length, int& second_length)
{
first_length = 10;
second_length = 9;
arrays = new int*[first_length];
for (int i = 0; i < first_length; ++i)
{
arrays[i] = new int[second_length];
for (int j = 0; j < second_length; ++j)
{
arrays[i][j] = first_length * i + j + 1;
}
}
return 0;
}
extern "C" __declspec(dllexport) int TwoArrayInMemoryFree(int**& arrays, int first_length)
{
for (int i = 0; i < first_length; ++i)
{
if (&arrays[i] != nullptr)
{
delete &arrays[i];
arrays[i] = nullptr;
}
}
return 0;
}
主要的c#调用导出:
[DllImport("DllTest.dll", EntryPoint = "add", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
public extern static int add(int a, int b);
[DllImport("DllTest.dll", EntryPoint = "OneArrayOutMemory", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
public extern static int OneArrayOutMemory(IntPtr arrays, int length);
[DllImport("DllTest.dll", EntryPoint = "OneArrayInMemoryFree", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
public extern static int OneArrayInMemoryFree(ref IntPtr arrays);
[DllImport("DllTest.dll", EntryPoint = "OneArrayInMemory", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
public extern static int OneArrayInMemory(ref IntPtr arrays, ref int length);
[DllImport("DllTest.dll", EntryPoint = "TwoArrayOutMemory", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
public extern static int TwoArrayOutMemory(ref IntPtr arrays, int first_length, int second_length);
[DllImport("DllTest.dll", EntryPoint = "TwoArrayInMemory", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
public extern static int TwoArrayInMemory(ref IntPtr arrays, ref int first_length, ref int second_length);
[DllImport("DllTest.dll", EntryPoint = "TwoArrayInMemoryFree", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
public extern static int TwoArrayInMemoryFree(ref IntPtr arrays, int first_length);
c#调用c++相关 首先是确定内存是谁来分配,一般推荐C#进行内存分配(个人理解,因为若c++分配,C#虽然不需要去关注具体内存,但是这种情况下C++更容易出现内存泄漏问题,在c#上进行管理应该更好一点)。
C#调用代码:
int count = 10;
int test = add(5, 10);
//一维数组 C#申请内存
IntPtr dataOne = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)) * count);
OneArrayOutMemory(dataOne, count);
for (int i = 0; i < count; ++i)
{
Console.WriteLine("data:" + Marshal.ReadInt32(dataOne, i * Marshal.SizeOf(typeof(int))));
}
//一维数组 c++申请内存
IntPtr dataOneCpp = IntPtr.Zero;
int length = 0;
OneArrayInMemory(ref dataOneCpp, ref length);
for (int i = 0; i < count; ++i)
{
Console.WriteLine("dataCPP:" + Marshal.ReadInt32(dataOneCpp, i * Marshal.SizeOf(typeof(int))));
}
OneArrayInMemoryFree(ref dataOneCpp);
//二维数组 c++申请内存
int first = 0;
int second = 0;
IntPtr dataInTwo = IntPtr.Zero;
TwoArrayInMemory(ref dataInTwo, ref first, ref second);
for (int i = 0; i < first; ++i)
{
int size = Marshal.SizeOf(typeof(IntPtr));
IntPtr newPtr = Marshal.ReadIntPtr(dataInTwo, size * i);
for (int j = 0; j < second; ++j)
{
int nowcount = Marshal.ReadInt32(newPtr, j * Marshal.SizeOf(typeof(int)));
Console.WriteLine("TwodataCPP:" + nowcount);
}
}
//二维数组 C#申请内存
int firstLength = 10;
int seconfLength = 9;
IntPtr dataTwo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)) * firstLength * seconfLength);
TwoArrayOutMemory(ref dataTwo, firstLength, seconfLength);
for (int i = 0; i < firstLength; ++i)
{
for (int j = 0; j < seconfLength; ++j)
{
int data = Marshal.ReadInt32(dataTwo, Marshal.SizeOf(typeof(int)) * (firstLength*i + j));
Console.Write(data + " ");
}
Console.WriteLine("");
}
注意:在C#分配的二维数组,只是简单从一维数组模拟出来的(个人理解,一般很少出现C#分配二维数组既指针list方式的情)。
其他的 都已实现。