c++ DLL 部分.
关于如何创建c++DLL , 呃, 就是注意
#ifdef YWSCOLLOCATIONDLL_EXPORTS
#define YWSCOLLOCATIONDLL_API __declspec(dllexport)
#else
#define YWSCOLLOCATIONDLL_API __declspec(dllimport)
#endif
这个宏定义,在后面修改的时候,记得把属性里面的 也改掉
而且注意,最好使用 __stdcall c的方式做约束
yws_collocationDLL.h
#ifdef YWSCOLLOCATIONDLL_EXPORTS
#define YWSCOLLOCATIONDLL_API __declspec(dllexport)
#else
#define YWSCOLLOCATIONDLL_API __declspec(dllimport)
#endif
//////////////////////////注意头文件的引用
#include <windows.h>
// TODO: 在此处引用程序需要的其他头文件
#include <iostream>
#include <stdlib.h>
#include <wchar.h>
// 此类导出自 yws_collocationDLL.dll
class YWSCOLLOCATIONDLL_API CywscollocationDLL {
public:
CywscollocationDLL(void);
// TODO: 在此添加您的方法。
};
extern YWSCOLLOCATIONDLL_API int nywscollocationDLL;
YWSCOLLOCATIONDLL_API int fnywscollocationDLL(void);
#pragma region //另一种方式定义一个函数.这里传入普通的数值
EXTERN_C YWSCOLLOCATIONDLL_API int __stdcall yws_AddMethod(int a, int b);
//EXTERN_C YWSCOLLOCATIONDLL_API int yws_AddMethod(int a, int b);
#pragma endregion
//c++ 为wchar_t 对应c# char 类型..
EXTERN_C YWSCOLLOCATIONDLL_API void __stdcall WriteString(wchar_t* content);
//c++中,传入const char* c#中传入string....
EXTERN_C YWSCOLLOCATIONDLL_API void __stdcall StringTochar(LPCTSTR content);
//这里使用传出字符串..
EXTERN_C YWSCOLLOCATIONDLL_API void __stdcall Cpp_PrintString(char charPtrLen[]);//char* charPtrLen
//指针的传递.
EXTERN_C YWSCOLLOCATIONDLL_API void __stdcall AddPtr(int *i);
//数组的传递.
EXTERN_C YWSCOLLOCATIONDLL_API void __stdcall AddIntArray(int *firstElement,int arrayLenght);
//数组传递方式二 不透明指针
EXTERN_C YWSCOLLOCATIONDLL_API void __stdcall AddIntArrayPtr(int *firstElementBuffer, int ArrayLenght);
//数组赋值
extern YWSCOLLOCATIONDLL_API int IntPtrLenght;
int * artptr;
EXTERN_C YWSCOLLOCATIONDLL_API int* __stdcall GetArray();
//函数指针
typedef void(_stdcall *CsCallBackMethod)(int tick);
EXTERN_C YWSCOLLOCATIONDLL_API void SetCallBack(CsCallBackMethod method);
//结构体的传递.
struct Vector3
{
float x, y, z;
};
EXTERN_C YWSCOLLOCATIONDLL_API void __stdcall SendStructFromCsToCPP(Vector3 vector);
//结构体指针的传入.
EXTERN_C YWSCOLLOCATIONDLL_API void __stdcall SendStructFromCsToCpp_ptr(Vector3 *vector);
//这里做一个比较复杂点的结构体的传入.
struct IStripe3DPoint
{
float u;
float v;
float x;
float y;
float z;
unsigned char R;
unsigned char G;
unsigned char B;
float p3x;
float p3y;
float p3z;
int ID;
};
//struct LPoint3d {
// float x; float y; float z;
//};
IStripe3DPoint *Lstrio_ptr;
EXTERN_C YWSCOLLOCATIONDLL_API IStripe3DPoint * __stdcall SendStripD3Point();
yws_collocationDLL.cpp
// 这是导出变量的一个示例
YWSCOLLOCATIONDLL_API int nywscollocationDLL=0;
// 这是导出函数的一个示例。
YWSCOLLOCATIONDLL_API int fnywscollocationDLL(void)
{
return 42;
}
//这是已导出类的构造函数。
//有关类定义的信息,请参阅 yws_collocationDLL.h
CywscollocationDLL::CywscollocationDLL()
{
return;
}
YWSCOLLOCATIONDLL_API int __stdcall yws_AddMethod(int a, int b)
{
return a + b;
}
YWSCOLLOCATIONDLL_API void __stdcall WriteString(wchar_t* content)
{
int num = WideCharToMultiByte(CP_OEMCP, NULL, content, -1, NULL, 0, NULL, FALSE);
char *pchar = new char[num];
WideCharToMultiByte(CP_OEMCP, NULL, content, -1, pchar, num, NULL, FALSE);
cout << pchar << endl;
}
YWSCOLLOCATIONDLL_API void __stdcall StringTochar(LPCTSTR content)
{
string sConts = LPSTR(content);
cout << sConts.c_str() << endl;
}
YWSCOLLOCATIONDLL_API void __stdcall Cpp_PrintString(char charPtrLen[])
{
char buf[] = "你好,我是在DLL中赋值成功的字符串..";
memcpy(charPtrLen,buf, sizeof(buf));
/*for (int i = 0; i < sizeof(buf); i++)
{
*charPtrLen++ = buf[i];
}*/
}
YWSCOLLOCATIONDLL_API void __stdcall AddPtr(int *i)
{
(*i)++;
}
YWSCOLLOCATIONDLL_API void __stdcall AddIntArray(int *firstElement, int arrayLenght)
{
int *currentPointer = firstElement;
for (int i = 0; i < arrayLenght; i++)
{
cout << currentPointer[i] << " ";
}
cout << endl;
}
YWSCOLLOCATIONDLL_API void __stdcall AddIntArrayPtr(int *firstElementBuffer,int ArrayLenght)
{
for (int i = 0; i < ArrayLenght; i++)
{
cout << firstElementBuffer[i] << " ";
}
cout << endl;
cout << "不透明指针输出完毕." << endl;
}
YWSCOLLOCATIONDLL_API int* __stdcall GetArray()
{
artptr = new int[10];
for (int i = 0; i < 10; i++)
{
artptr[i] = i;
}
return artptr;
}
YWSCOLLOCATIONDLL_API void SetCallBack(CsCallBackMethod method)
{
int tick = rand()/20;
method(tick);
}
YWSCOLLOCATIONDLL_API void __stdcall SendStructFromCsToCPP(Vector3 vector)
{
cout << "get vector3 int cpp, x: " << vector.x << " ,y: " << vector.y << " ,z: " << vector.z << endl;
}
YWSCOLLOCATIONDLL_API void __stdcall SendStructFromCsToCpp_ptr(Vector3 *vector)
{
vector->x += 100;
cout << "get vector3 int cpp, x: " << vector->x << " ,y: " << vector->y << " ,z: " << vector->z << endl;
}
YWSCOLLOCATIONDLL_API IStripe3DPoint* __stdcall SendStripD3Point()
{
if (Lstrio_ptr != NULL)
{
delete[] Lstrio_ptr;
Lstrio_ptr = NULL;
}
Lstrio_ptr = new IStripe3DPoint[10];
for (int i = 0; i < 10; i++)
{
Lstrio_ptr[i].B = i;
Lstrio_ptr[i].G = 3;
Lstrio_ptr[i].R = 98;
Lstrio_ptr[i].x = Lstrio_ptr[i].y = Lstrio_ptr[i].z = i * 4;
Lstrio_ptr[i].p3x = Lstrio_ptr[i].p3y = Lstrio_ptr[i].p3z = i * 5;
}
return Lstrio_ptr;
}
到此,编译 输出
.net 程序里,对DLL里api的封装
//此函数引入cpp dll,作为c++dll的映射函数..
public class Mvpi_yws_DLL
{
//数值相加
[DllImport(@"YWSCOLLOCATIONDLL.dll", EntryPoint = @"yws_AddMethod")]
public extern static int yws_AddMethod(int a, int b);
//w_char字符传递
[DllImport(@"YWSCOLLOCATIONDLL.dll", EntryPoint = @"WriteString")]
extern unsafe static void WriteString(char* contend);
public static unsafe void yws_WriteString(string content)
{
fixed (char* p = &(content.ToCharArray()[0]))
{
WriteString(p);
}
}
//字符串传递
[DllImport(@"YWSCOLLOCATIONDLL.dll", EntryPoint = @"StringTochar")]
extern unsafe static void StringTochar(char* contend);
public static unsafe void yws_StringTochar(string content)
{
char* outF = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(content).ToPointer();
StringTochar(outF);
}
//字符串输出
[DllImport(@"YWSCOLLOCATIONDLL.dll", EntryPoint = @"Cpp_PrintString")]
extern static void Cpp_PrintString(StringBuilder charPtrLen);
//销毁
[DllImport(@"YWSCOLLOCATIONDLL.dll", EntryPoint = @"DesTroystr")]
extern unsafe static void DesTroystr();
public static void yws_cppPrintStr()
{
StringBuilder strb = new StringBuilder();
strb.Capacity = 1000;
Cpp_PrintString(strb);
Console.WriteLine(strb);
}
//指针传递
[DllImport(@"YWSCOLLOCATIONDLL.dll", EntryPoint = @"AddPtr")]
public extern unsafe static void AddPtr(int* contend);
public static unsafe void yws_addPtr(ref int i)
{
int temp = i;
AddPtr(&temp);
i = temp;
}
//数组传递.方式一
[DllImport(@"YWSCOLLOCATIONDLL.dll", EntryPoint = @"AddIntArray")]
public extern unsafe static void AddIntArray(int* firstElement, int arrayLenght);
public static unsafe void yws_AddIntArray(int[] buffer, int bufferLenght)
{
bufferLenght = buffer.Length;
fixed (int* k = &buffer[0])
{
AddIntArray(k, bufferLenght);
}
}
//数组传递方式二 这里使用不透明指针来完成数组传入...
[DllImport(@"YWSCOLLOCATIONDLL.dll",EntryPoint = @"AddIntArrayPtr")]
public extern unsafe static void AddIntArrayPtr(IntPtr firstElementBuffer, int ArrayLenght);
public static void yws_AnotherMethod(int[] buffer)
{
int bufferLen = buffer.Length;
GCHandle dllfind = GCHandle.Alloc(buffer,GCHandleType.Pinned);
if(dllfind.IsAllocated == true)
{
AddIntArrayPtr(dllfind.AddrOfPinnedObject(),bufferLen);
}
else
{
Console.WriteLine("地址分配失败..");
}
dllfind.Free();
}
//数组赋值.
[DllImport(@"YWSCOLLOCATIONDLL.dll", EntryPoint = @"GetArray")]
public extern unsafe static int* GetArray();
public unsafe static void yws_GetArray()
{
int* pArrayPointer = null;
pArrayPointer = GetArray();
for(int i=0;i<10;i++)
{
Console.Write(pArrayPointer[i].ToString()+" ");
}
}
//函数指针与委托.
public delegate void CsCallBackMethod(int tick);
[DllImport(@"YWSCOLLOCATIONDLL.dll", EntryPoint = @"SetCallBack")]
public extern static void SetCallBack(CsCallBackMethod method);
static CsCallBackMethod callBack;
static void CsCallBackFuntion(int tick)
{
Console.WriteLine(tick.ToString());
}
public static void yws_SetCallBack()
{
callBack = CsCallBackFuntion;
SetCallBack(callBack);
}
//传递结构体.
[DllImport(@"YWSCOLLOCATIONDLL.dll", EntryPoint = @"SendStructFromCsToCPP")]
public extern static void SendStructFromCsToCPP(Vector3 vector);
//传递结构体指针,并修改之..
[DllImport(@"YWSCOLLOCATIONDLL.dll", EntryPoint = @"SendStructFromCsToCpp_ptr")]
public extern static void SendStructFromCsToCpp_ptr(ref Vector3 vector);
//自定义结构体数组测试.
[DllImport(@"YWSCOLLOCATIONDLL.dll", EntryPoint = @"SendStripD3Point")]
public extern unsafe static IStripe3DPoint* SendStripD3Point();
public static unsafe void yws_sendStripD3Point()
{
IStripe3DPoint* pArrayPointer = null;
pArrayPointer = SendStripD3Point();
for (int i = 0; i < 10; i++)
{
Console.WriteLine(string.Format("数组: {0} {1} {2} {3} {4} {5} {6} {7} {8} {9}",i, pArrayPointer[i].x, pArrayPointer[i].y, pArrayPointer[i].z,
pArrayPointer[i].R, pArrayPointer[i].B, pArrayPointer[i].G,
pArrayPointer[i].p3x, pArrayPointer[i].p3y, pArrayPointer[i].p3z));
}
}
}
[StructLayout(LayoutKind.Sequential)]
public struct Vector3
{
public float x, y, z;
}
[StructLayout(LayoutKind.Sequential)]
public struct IStripe3DPoint
{
public float u;
public float v;
public float x;
public float y;
public float z;
public byte R;
public byte G;
public byte B;
public float p3x;
public float p3y;
public float p3z;
public int ID;
};
创建.net 程序,将上面生成的DLL放到 和 .exe 目录里, .net 部分调用
class Program
{
static void Main(string[] args)
{
Console.WriteLine("调用C++非托管DLL 开启\r\n");
int result = Mvpi_yws_DLL.yws_AddMethod(10,20);
Console.WriteLine("计算结果: "+ result.ToString());
string tem = "程序运行,性能开启测试....\r\n";
Mvpi_yws_DLL.yws_WriteString(tem);
Mvpi_yws_DLL.yws_cppPrintStr();
Mvpi_yws_DLL.yws_StringTochar("程序运行,性能开启测试二.....");
int result2 = 15;
Mvpi_yws_DLL.yws_addPtr(ref result2);
Console.WriteLine("\r\n 计算结果:"+result2.ToString()+"\r\n");
//数组
int[] buf = { 1,23,45,66,77,88};
Mvpi_yws_DLL.yws_AddIntArray(buf, buf.Length);
//数组赋值二:
int[] buf2 = { 23,44,55,657,3,8};
Mvpi_yws_DLL.yws_AnotherMethod(buf2);
//获取赋值之后的数据...
Console.WriteLine();
Mvpi_yws_DLL.yws_GetArray();
Console.WriteLine();
//函数指针的处理..
Mvpi_yws_DLL.yws_SetCallBack();
//传递结构体..
Vector3 vector = new Vector3() { x = 10,y =33,z =99 };
Mvpi_yws_DLL.SendStructFromCsToCPP(vector);
//传递结构体指针
Mvpi_yws_DLL.SendStructFromCsToCpp_ptr(ref vector);
Console.WriteLine("改变之后的数值: "+vector.x.ToString());
//自定义结构体指针数组..
Console.WriteLine();
Mvpi_yws_DLL.yws_sendStripD3Point();
Console.WriteLine("\r\n调用C++非托管DLL 结束");
Console.ReadKey();
}
}
运行:
这个就是效果图, 大家记得把**.net程序 要 勾选 不安全代码 选项** ,
有了这个, .net 和c++基本上,就可以完全不用担心了