C#项目调用C++的DLL程序

本程序参考:http://www.cnblogs.com/liping13599168/archive/2011/03/31/2000320.html

但是本程序需要说明一个非常重要的问题:

就是注意你注意DLL文件和调用它的位数上一定要一致;否则会出现错误;

本人使用的是X64架构的系统;所以这个要遵守;

首先创建一个C++解决方案;其次在下面的选项里面选择win32项目,这个一定注意; 不要选控制台或者MFC程序;

然后再程序设置中选择DLL;其他默认即可;

最后得到了下面的界面;

我们可以看到这里有一些文件,其中dllmain.cpp作为定义DLL应用程序的入口点,它的作用跟exe文件有个main或者WinMain入口函数是一样的,它就是作为DLL的一个入口函数,实际上它是个可选的文件。它是在静态链接时或动态链接时调用LoadLibrary和FreeLibrary时都会被调用。

以下是要注意的部分了:一定要对下面的Debug部分进行更改;这一点就是X64配合的主要步骤;

配置管理器更改如下图;

然后再CppDemo.cpp中输入以下代码:

//以下是我写的程序;
extern "C" __declspec(dllexport) int Sub(int x, int y)
{
	return x - y;
}

extern "C" __declspec(dllexport) int Multiply(int x, int y)
{
	return x * y;
}
extern "C" __declspec(dllexport) int Add(int x, int y)
{
	return x + y;
}
extern "C" __declspec(dllexport) int Divide(int x, int y)
{
	return x / y;
}

extern "C" 包含双重含义,从字面上即可得到:首先,被它修饰的目标是“extern”的;其次,被它修饰的目标是“C”的。而被extern "C"修饰的变量和函数是按照C语言方式编译和连接的。

__declspec(dllexport)的目的是为了将对应的函数放入到DLL动态库中。

extern "C" __declspec(dllexport)加起来的目的是为了使用DllImport调用非托管C++的DLL文件。因为使用DllImport只能调用由C语言函数做成的DLL。

下面创建C#控制台程序;

赋值CppDemo中的dll文件到 C#程序目录的X64的运行目录中

并且添加类:

public class CPPDLL
    {
        [DllImport("CppDemo.dll")]
        public static extern int Add(int x,int y);
        [DllImport("CppDemo.dll")]
        public static extern int Sub(int x, int y);
        [DllImport("CppDemo.dll")]
        public static extern int Multiply(int x, int y);
        [DllImport("CppDemo.dll")]
        public static extern int Divide(int x, int y);

    }

然后再在主程序中写入:

int result = CPPDLL.Add(10, 20);
            Console.WriteLine("10 + 20 = {0}", result);

            result = CPPDLL.Sub(30, 12);
            Console.WriteLine("30 - 12 = {0}", result);

            result = CPPDLL.Multiply(5, 4);
            Console.WriteLine("5 * 4 = {0}", result);

            result = CPPDLL.Divide(30, 5);
            Console.WriteLine("30 / 5 = {0}", result);

            Console.ReadLine();

运行结果如下:

下面说说类调用:

首先在CppDemo中添加一个UserInfo这个类:

其中,UserInfo.h  中添加下面程序;

class UserInfo
{
private:
	char* m_Name;
	int m_Age;
public:
	UserInfo(char* name, int age)
	{
		m_Name = name;
		m_Age = age;
	}
	virtual ~UserInfo(){ } //这里的virtual是留待以后实现的意思;
	int GetAge() { return m_Age; }
	char* GetName() { return m_Name; }
};

UserInfo.cpp的内容如下:

#include "stdafx.h"
#include "malloc.h"
#include "UserInfo.h"

typedef struct {
	char name[32];
	int age;
} User;//定义一个结构体命名为为User;

UserInfo* userInfo;//声明一个指向UserInfo对象的指针;

//下面这个是接口,返回一个指针指向的地址;
//注意:代码中的User*是个指针,返回也是一个对象指针,这样做为了防止方法作用域结束后的局部变量的释放。
extern "C" __declspec(dllexport) User* Create(char* name, int age)
{
	//malloc 向系统申请分配指定size个字节的内存空间。
	//返回类型是 void* 类型。void* 表示未确定类型的指针。
	User* user = (User*)malloc(sizeof(User));//分配给user一块内存;再用User进行格式化;

	userInfo = new UserInfo(name, age);

	//复制;
	strcpy(user->name, userInfo->GetName());
	user->age = userInfo->GetAge();

	return user;
}

然后再在我们之前建立的C#程序中添加:

在项目中CPPDLL类中添加代码:

//类调用程序块;
        [DllImport("CppDemo.dll")]
        public static extern IntPtr Create(string name, int age); //IntPtr是表示平台特定指针,使用时指定;

        //StructLayout特性允许我们控制Structure语句块的元素在内存中的排列方式,
        //以及当这些元素被传递给外部DLL时,运行库排列这些元素的方式。
        [StructLayout(LayoutKind.Sequential)] //控制结构体字段的物理布局;括号中的意思是按出现顺序依次布局;
        public struct User
        {
            //MarshalAs属性指示如何在托管代码和非托管代码之间封送数据。
            //下面说明两个字段的数据占的能存大小,第一个是字符类型;第二个是32位int类型;
            //它有两个参数,所以能管到下面两行;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string Name;
            public int Age;
        }

在主程序中添加如下代码:

//下面是类的调用
            IntPtr ptr = CPPDLL.Create("Shawn", 25);
            //转换指针为User类型;因为返回的是一个object,所以要格式化成User;
            CPPDLL.User user = (CPPDLL.User)Marshal.PtrToStructure(ptr, typeof(CPPDLL.User));
            Console.WriteLine("Name: {0}, Age: {1}", user.Name, user.Age);

注意对C#程序进行重新编译

运行结果如下;

时间: 2024-10-06 22:34:01

C#项目调用C++的DLL程序的相关文章

SQLSERVER调用DLL程序

在SQL Server中调用dll分为两个步骤 1.创建一个dll文件(dll文件分成3种类型,讲其中一种) 2.把dll文件放进SQL Server的程序集中.然后定义一个Function,就可以通过该Function来引用dll中的函数. 1创建一个dll文件 1.1点击“文件”->“新建”->“项目”->类库,把命名空间改成TestDLL,添加如下代码 (框架必须改为.NET3.5及3.5以下,因为SQL Server 2008只是支持.NET 3.5及一下,.NET 4.0是20

64位进程调用32位dll的解决方法 / 程序64位化带来的问题和思考

最近做在Windows XP X64,VS2005环境下做32位程序编译为64位程序的工作,遇到了一些64位编程中可能遇到的问题:如内联汇编(解决方法改为C/C++代码),long类型的变化,最关键的遇到了64位进程需要调用32位dll的问题.由于有一些32位dll没有源代码,无法重新编译为64位dll,所以只能想办法解决64位进程调用32位dll问题,这个问题让我很是挠头了几天. 相关资料:微软公司的官方网站针对这个问题描述如下:在64位的windows系统中,一个64位进程不能加载一个32位

在Windows Phone项目中调用C语言DLL

在Windows Phone项目中调用C语言写的DLL 最近接到一个需求,需要在WP里调用一个C语言写的DLL,并且说Android和iOS都可以,问我WP是否可以这样? 我说我调研一下,就有了下面的文章. 在传统C# WinForm 里调用Win32 DLL都不容易(可能用惯了C#),要用P/Invoke,然后DllImport什么什么,那WP里不是更麻烦? 先看看网上有没有可用的文章,结果还真找到devdiv中的文章,但其中有两处错误,所以我fix bug并且整理一下,然后展示给大家. 1.

Qt DLL总结【二】-创建及调用QT的 DLL(三篇)good

目录 Qt DLL总结[一]-链接库预备知识 Qt DLL总结[二]-创建及调用QT的 DLL Qt DLL总结[三]-VS2008+Qt 使用QPluginLoader访问DLL 开发环境:VS2008+Qt4.7.4 最近看了不少Qt的DLL例子,总结一下如何创建和调用QT 动态链接库. 先讲一下对QT动态链接库的调用方法,主要包括: 1.显式链接DLL,调用DLL的全局函数,采用Qt的QLibrary方法 2.显示链接DLL,调用DLL中类对象.成员函数.(通过对象即可实现类成员函数的调用

.Net 环境下C# 通过托管C++调用本地C++ Dll文件

 综述 : 本文章介绍.Net 环境下C# 通过托管C++调用本地C++ Dll文件, 示例环境为:VS2010, .Net4.0, Win7. 具体事例为测试C++, C#, 及C#调用本地C++Dll文件进行浮点运算效率的一部分. 如果需要查看三者的效率, 请继续阅读下面的文章. a 创建本地CPP类库 1. 创建本地CPP的Dll ---->EfficiencyNativeCPPDLL 2. 点击下一步 注意选择为DLL(D)项, 然后选择完成. 3.书写DLL文件 3.1 Efficie

Qt DLL总结【二】-创建及调用QT的 DLL

开发环境:VS2008+Qt4.7.4 最近看了不少Qt的DLL例子,总结一下如何创建和调用QT 动态链接库. 先讲一下对QT动态链接库的调用方法,主要包括: 1.显式链接DLL,调用DLL的全局函数,采用Qt的QLibrary方法 2.显示链接DLL,调用DLL中类对象.成员函数.(通过对象即可实现类成员函数的调用) ①用虚函数表的方法,这也是COM使用的方法,利用Qt的QLibrary技术调用: ②用GetProcAddress直接调用. ③用Qt的QPluginLoader类直接调用生成的

C#调用C++的dll及MATLAB的dll的方法(一)

为了记录踩坑的过程,避免以后再踩坑,居然专门开通了这么专业的技术博客,正好督促自己以后好好研究技术. 最近需要做一个界面系统来包装一下之前做的人脸属性识别的模型,希望用户随机选取一张图像(后面会实现摄像头拍现场图像),系统自动给出该图像中所包含的人脸属性(有没有戴眼镜,有没有戴帽子之类的).其中人脸属性预测之前需要进行人脸识别以及人脸对齐等操作,人脸属性识别是由C++写的,人脸对齐是由MATLAB写的,考虑到界面的友好性以及开发的难易性,最终选了C#作为开发语言.(不要问我为啥不用Java,因为

C#调用C/C++ dll文件 的简单示例

测试环境:VS2010 windows7 1.文件->新建项目,选择win32 控制台程序,输入项目名称dll_test,然后点击确定 2. 3.点击下一步 4.选择dll 点击完成 ,点击dll_test.cpp 文件 extern "C" __declspec(dllexport) int add(int a,int b); int add(int a,int b) { return a+b; } 说明:(这里是.cpp 文件不是.c 文件,所以要加extern "

【转】 编写C#调用的C++DLL

最近一段时间,经常遇到这些问题,前一阵子研究了一下,没有记下来,没想到最近研究又有些不记得了,今天把它写下来以备忘. 一般我们提供给其他语言调用的DLL,都是用C或者C++编写,然后封装.我这边也是采用的C++. 首先有几个注意点: 1.如果功能很简单,或者不使用第三方库(如MFC自带的库),建立一个win32的控制台程序就可以了,然后把项目生成改为DLL.值得一提的是,代码生成里面 运行时库分四种: (1)多线程MTD(静态库,编译之后,你的lib带有调试功能)——> debug时用 (2)多