此次示例包含了常用类型参数的转换及传递包括
1) 基本类型:int, unsigned char, float, double等
2) 指针类型;
3) 引用
4) 一维数组、二维数组
5) 简单结构体
6) 结构体中包含数组
7) 字符串类型
8) bool类型
后续再进行其它 类型的封装,如
9) 函数指针与回调函数
10) 类
下面结合代码对这些类型
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文件来实现。