C#调用C/C++ 动态链接库DLL(二)
下面结合代码对这些类型
1。 创建一个C++ 动态链接库的工程
实现文件dlldemo.cpp,内容如下
#include <stdlib.h> #include <iostream> #include <cmath> #include "dlldemo.h" int __stdcall PassString(char* msg) { std::cout<<"msg:"<<msg<<std::endl; return 0; } long double __stdcall Power(double x, int y) { return pow(x, y); } double __stdcall GetDistance2D(Location p1, Location p2) { return sqrt( (p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y) ); } int __stdcall GetDistance1D(int x1, int x2) { return abs(x1 - x2); } int __stdcall GetValues(int **values,int width, int height) { if( values == NULL || *values == NULL) return -1; for(int i=0; i<width; ++i){ for(int j=0; j<height; ++j){ values[i][j] = i*j; } } return width * height; } int __stdcall CopyValues(int* dst, int* src, int length) { if( dst == NULL || src == NULL || length < 0) return -1; memmove(dst, src, sizeof(int)*length); return length; } int __stdcall GetValue(int& dst) { return dst = 0x1155; } int __stdcall CopyArray2D(unsigned char** dst, unsigned char** src, int m, int n) { if(dst == NULL || src == NULL || m <= 0 || n <= 0) return -1; memmove(dst[0],src[0],m * n * sizeof(unsigned char)); return m * n; } int __stdcall CopyPointerArray2D(unsigned char** dst, unsigned char** src, int m, int n) { if(dst == NULL || src == NULL || m <= 0 || n <= 0) return -1; for(int i=0; i<m; ++i){ for(int j=0; j<n; ++j){ dst[i][j] = src[i][j]; } } return m * n; } bool __stdcall GetPerson(Person* p, char* name) { if( name == NULL || p == NULL) return false; p->age = sizeof(bool); p->age = 100; strcpy(p->name, "Steve Jobs"); strcpy(p->email, "Steve.Jobs@apple.com"); p->isFemale = 0; return true; } int __stdcall SetEnable(bool enabled) { return enabled; }
头文件dlldemo.h内容如下:
#ifndef DLLDEMO_H_H #define DLLDEMO_H_H extern int __stdcall GetValues(int **values,int width, int height); extern int __stdcall PassString(char* msg); extern long double __stdcall Power(double x, int y); struct Location{ int x; int y; }; double __stdcall GetDistance2D(Location p1, Location p2); int __stdcall GetDistance1D(int x1, int x2); extern int __stdcall CopyValues(int* dst, int* src, int length); extern int __stdcall GetValue(int& dst); extern int __stdcall CopyArray2D(unsigned char** dst, unsigned char** src, int m, int n); extern int __stdcall CopyPointerArray2D(unsigned char** dst, unsigned char** src, int m, int n); struct Person{ char name[20]; unsigned char age; bool isFemale; // can NOT be bool char email[50]; }; extern bool __stdcall GetPerson(Person* p, char* name); extern int __stdcall SetEnable(bool enabled); #endif
因为要导出函数,还要创建一个导出文件dlldemo.def
LIBRARY dlldemo EXPORTS GetValues PassString Power GetDistance1D GetDistance2D CopyValues GetValue CopyArray2D CopyPointerArray2D GetPerson SetEnable
因为C++函数实际生成的名称与我们看到的名称是不一样的,所以直接在C++代码中使用
__declspec(dllexport) 导出的函数在C#中找不到,需要用.def文件来实现。