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++基本上,就可以完全不用擔心了