在实际项目工作中,经常用到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. tomcat配置虚拟主机

    在眼下,非常多server都是一台server对外能够訪问非常多个javaEE的项目,这样的实现方式就须要在tomcat里面配置虚拟主机了!以下就说说怎样配置虚拟主机: 找到tomcat的安装文件夹, ...

  2. [AngularJS] Isolate State Mutations in Angular Components

    Managing state is one of the hardest things to do in any application. Angular 2 tackles this problem ...

  3. ios 字典转模型

    <pre name="code" class="objc">#import <Foundation/Foundation.h> @int ...

  4. Helpers\Pagination

    Helpers\Pagination Break recordset into a series of pages. First create a new instance of the class ...

  5. 小白日记11:kali渗透测试之服务扫描-banner、dmitry、nmap特征库、操作系统识别、SNMP

    服务扫描 不能单纯的以端口辨别服务.很多网络服务是漏洞频发的高危对象,对网络上的特定服务进行扫描,往往能让我们少走弯路,增加渗透成功的几率.确定开放端口后,通常会对相应端口上所运行服务的信息进行更深入 ...

  6. Content-Type一览

    文件扩展名 Content-Type(Mime-Type) 文件扩展名 Content-Type(Mime-Type) .*( 二进制流,不知道下载文件类型) application/octet-st ...

  7. css实现居中

    --在html常常用到居中 --1.可以用<center></center> --2.可以用css 演示代码: <!DOCTYPE html PUBLIC "- ...

  8. SQL Server select into/bulkcopy用法

    select into/bulkcopy用法 一.背景 如何提升批量插入效率,各位看官,瞧好了! exec sys.sp_dboption '数据库名','select into/bulkcopy', ...

  9. Oracle启动的整个过程

    1.启动选项 在发出startup命令启动数据库时,oracle将在默认位置$ORACLE_HOME/dbs(UNIX/Linux)中查找初始化参数文件.Oracle将以下面的顺序在其中寻找合适的初始 ...

  10. 转:iOS基于MVC的项目重构总结

    转:http://www.cocoachina.com/ios/20160519/16346.html 关于MVC的争论 关于MVC的争论已经有很多,对此我的观点是:对于iOS开发中的绝大部分场景来说 ...