在实际项目工作中,经常用到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. [ES6] 19. for ... of

    In ES5, we have for ... in: var phones = ["iPhone", "Nexus", "Nokia"]; ...

  2. Allegro批量复制Via并保持net属性

    使用Allegro时须要批量复制net属性是GND或是其他属性的Via: 批量选中Via后点击Copy或'Shift+F5' 然后完毕复制,如图: 复制完.我们可能发现,这些复制的Via的net属性不 ...

  3. gdb在运行maintenance info program-spaces命令时coredump

    coredump时的信息: (gdb) maintenance info program-spaces *** Error in `gdb': free(): invalid pointer: 0x0 ...

  4. c#线程--生产者和消费者

    using System; using System.Collections; using System.Collections.Generic; using System.Linq; using S ...

  5. CentOS5.6 安装RabbitMQ

    步骤参考官方地址:http://www.rabbitmq.com/install-rpm.html我们这个版本按照官方的不能正确安装. 1.安装erlang(官网地址http://www.erlang ...

  6. iOS,面试必看,最全梳理

    序言 目前形势,参加到iOS队伍的人是越来越多,甚至已经到供过于求了.今年,找过工作人可能会更深刻地体会到今年的就业形势不容乐观,加之,培训机构一火车地向用人单位输送iOS开发人员,打破了生态圈的动态 ...

  7. Mysql学习笔记之常用数据类型 (转)

    http://www.cnblogs.com/doit8791/archive/2012/05/11/2495319.html 数据类型是定义列中可以存储什么数据以及该数据实际怎么存储的基本规则.My ...

  8. js实现归并排序

    function merge(s_arr, d_arr, start, middle, end){ var s_temp = start; var m_temp = middle+1; var tem ...

  9. LeetCode 338

    Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the ...

  10. Scala中的构造器和高阶函数

    构造器 在定义类时可以定义主构造器.主构造器可以同时声明字段. /** * 主构造器 * @author Administrator */ //在scala中,类和方法交织在一起 class Test ...