在实际项目工作中,经常用到C#调用C++ 或者C编写的dll文件。

dll支持一般函数声明和类的定义声明,但是一般为了简化,都是 采用函数声明的方式。这里主要并不是写 dll的编写。

先在vs中创建一个dll项目

添加一个新的cpp文件 测试代码如下:

struct Student   //定义了一个结构体,结构体中包含了基本类型,字符串类型和数组,基本上能满足很多情况了
{
int no;
char name[10];
int score[4];
};

extern "C" __declspec(dllexport) void __stdcall returnString(char* s)  //这是返回一个字符串的方法,和下面的可以作为对比。即返回字符串可以将字符串的指针作为参数或者作为函数返回值这两种方式
{
strcpy(s,"123456");
}

//extern "C" __declspec(dllexport) char* __stdcall returnString()
//{
// return "aaaaaa";
//}

extern "C" __declspec(dllexport) int __stdcall returnInt() //这是一个基本功能,返回了一个基本类型的值
{
return 123;
}

extern "C" __declspec(dllexport) void __stdcall returnIntArray(int *a) // 这是返回了一个基本类型的数组
{
for (int i=0;i<10;i++)
{
a[i] = i+1;
}
}

extern "C" __declspec(dllexport) void __stdcall returnStruct(Student & stu) //这是返回了一个结构体类型   注意:为什么我们一般在返回时使用参数返回,而不是使用函数体返回,因为有的时候会需要返回多个参数值,我们就一致习惯采用这种方式
{
stu.no = 100;
strcpy(stu.name,"csl");
for (int j=0;j<4;j++)
{
stu.score[j] = j*2+14;
}
}

//extern "C" __declspec(dllexport) void __stdcall returnStructArray(Student* stu) //这是返回了一个结构体指针类型,即返回值是一个结构体数组,可以返回多个结构体对象 和下面的方式是一样的
//{
// //stu = (Student*)malloc(sizeof(Student)*10);
// for (int i=0;i<10;i++)
// {
// stu[i].no = i+1;
// strcpy(stu[i].name,"csl");
// }
//
//}

extern "C" __declspec(dllexport) void __stdcall returnStructArray(Student stu[])
{
//stu = (Student*)malloc(sizeof(Student)*10);
for (int i=0;i<10;i++)
{
stu[i].no = i+1;
strcpy(stu[i].name,"csl");
for (int j=0;j<4;j++)
{
stu[i].score[j] = j*2+14;
}
}

}

------------C#中的调用---------------

public struct Student
{
public int no;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
public string name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] // 指定数组尺寸
public Int32[] score;
}; //结构体声明

//调用函数的声明

[DllImport("E:\\C#\\TestLibDLL\\Debug\\TestLibDLL.dll")]
public static extern void returnString(StringBuilder s); // 字符串类型直接使用stringbuilder

[DllImport("E:\\C#\\TestLibDLL\\Debug\\TestLibDLL.dll")]
public static extern int returnInt();//返回基本类型

[DllImport("E:\\C#\\TestLibDLL\\Debug\\TestLibDLL.dll")]
public static extern void returnIntArray(int[] a); //返回数组 因为数组是引用类型,所以直接这么声明

[DllImport("E:\\C#\\TestLibDLL\\Debug\\TestLibDLL.dll")]
public static extern void returnStruct(out Student stu); //返回结构体 因为C++定义中使用得&引用,所以我们C#中需要使用out or  ref

[DllImport("E:\\C#\\TestLibDLL\\Debug\\TestLibDLL.dll")] 
public static extern void returnStructArray(IntPtr ptr); //对于返回结构体的数组,网上的说法是使用MarshalAs操作内存指针 自己试过用 student[]数组作为参数,得不到结果 ,使用指针的确可以

//具体操作

static void Main(string[] args)
{
//string s ;
// s = returnString();
//Console.WriteLine(s);

StringBuilder s = new StringBuilder();
returnString(s);
Console.WriteLine(s.ToString());

int nInt = returnInt();
Console.WriteLine(nInt);

int[] arrayList = new int[10];
returnIntArray(arrayList);

Student stu = new Student();
returnStruct(out stu);

Student[] stus = new Student[10];

int size = Marshal.SizeOf(typeof(Student)) * 10;
IntPtr ptr = Marshal.AllocHGlobal(size);
returnStructArray(ptr);
for (int i = 0; i < 10; i++)
{
IntPtr temp = (IntPtr)(UInt32)(ptr + i * size / 10);
stus[i] = (Student)Marshal.PtrToStructure(temp, typeof(Student));
}
Marshal.FreeHGlobal(ptr); //释放内存

Console.ReadKey();
}

对C#调用C++ dll文件进行总结的更多相关文章

  1. Java调用第三方dll文件的使用方法 System.load()或System.loadLibrary()

    Java调用第三方dll文件的使用方法 public class OtherAdapter { static { //System.loadLibrary("Connector") ...

  2. C#调用C++ DLL 文件

    说来惭愧,都注册一年多了,却没有发表过一篇正式的博文,中间很多学习的过程也没有记录下来.如今到了一个新的环境,也有了学习的机会,一定要把每天的收获记录一下. 要做的东西需要引用C++编写的DLL,刚开 ...

  3. java调用c#dll文件配置

    1 在强大的c#语言和java语言之间,二者难免会因为某些特殊的要求会相互调用. 下面就以java调用c#的dll为例做详细介绍 1  在vs中的环境设置如下图,图片中程序仅作为讲解程序,在项目编译成 ...

  4. VS2010 C#调用C++ DLL文件 【转】

    http://www.soaspx.com/dotnet/csharp/csharp_20110406_7469.html 背景 在项目过程中,有时候你需要调用非C#编写的DLL文件,尤其在使用一些第 ...

  5. 用vc生成可被python调用的dll文件

    前提已经有.c 和.i文件 用swid编译了.i文件生成了wrap.c文件和.py文件 vc创建dll工程 将.h加入到头文件中.c文件和wrap.c文件添加到源文件中 将.i文件添加到工程目录下To ...

  6. 制作和unity调用动态链接库dll文件

    首先用vc建立一个dll工程 然后在里面建立一个testunity.h文件.内容如下 1 extern "C" int _declspec(dllexport)testunity( ...

  7. unity调用C++ dll文件

    首先建立Plugins文件夹,把dll文件放在里面 一一对应,我踩的坑是文件名加了后缀.dll,虽然不知道网上为什么都加了我这加了就报找不到dll文件错误,反正解决啦

  8. C#调用C++dll文件 运行提示找不到函数的入口点

    1.首先用DllAnalyzer查看dll的输出函数名,发现输出的函数名有所变化,多了@xxx和一些别的奇怪的字符,实际上是因为C++重载机制造成的,使用使用extern "C"关 ...

  9. VS2010 C#调用C++ DLL文件

    http://www.soaspx.com/dotnet/csharp/csharp_20110406_7469.html http://www.cnblogs.com/warensoft/archi ...

随机推荐

  1. C++ C++ 控制台程序 设置图标

    . 实现过程 创建1个控制台程序. 新建1个 Resource Script文件 #include "stdio.h" #include <windows.h> #in ...

  2. oracle internal: VIEW: X$KCBKPFS - PreFetch Statistics - (9.0)

    WebIV:View NOTE:159898.1     Note (Sure) - Note    Mods - Note Refs Error ORA 600 TAR TAR-Info Bug B ...

  3. iOS开发——Swift篇&文件,文件夹操作

    文件,文件夹操作   ios开发经常会遇到读文件,写文件等,对文件和文件夹的操作,这时就可以使用NSFileManager,NSFileHandle等类来实现. 下面总结了各种常用的操作:   1,遍 ...

  4. js 控制div 显示隐藏的问题

    var divs = document.getElementsByTagName("div");得到所有的divfor(var i=0;i<divs.length;i++){ ...

  5. 修改mac os分辨率(VMware)

    转自:http://hi.baidu.com/hehonglei123/item/55591c17e7991d582a3e22a1 1. 在Mac系统中安装VMsvga2:VMsvga2_v1.2.3 ...

  6. qsort函数、sort函数 (精心整理篇)

    先说明一下qsort和sort,只能对连续内存的数据进行排序,像链表这样的结构是无法排序的. 首先说一下, qsort qsort(基本快速排序的方法,每次把数组分成两部分和中间的一个划分值,而对于有 ...

  7. Linux(Debian) vps安装gnome桌面+VNC

      昨天转载了一篇关于在Linux VPS上安装xface桌面并VNC连接的文章,因为文章是基于CentOS系统来操作的,有热心读者希望有一个Debian下的类似的东西,这就促成了今天的这篇文字.需要 ...

  8. 前端必会css整理

    1.设置css样式的三种方式?         外部样式表,引入一个外部css文件         内部样式表,将css代码放在<head>标签内部         内联样式,将css样式 ...

  9. javascript 关于语义化作用的理解

    看代码实例1 var a=1; function m(a){ //此处为形参第一个传入函数的参数,既为arguments[0] alert(a); //此处a为与形参绑定的 } m(a);//1 此时 ...

  10. 3.4.2内核下的I2C驱动

    1. 框架1.1 硬件协议简介1.2 驱动框架1.3 bus-drv-dev模型及写程序a. 设备的4种构建方法a.1 定义一个i2c_board_info, 里面有:名字, 设备地址 然后i2c_r ...