-
2020-11-02 16:14:02
C调用C++接口,这个问题的解决和C++调用C动态链接库是类似的。话不多说,直接上例子来进行说明。
helloworld_cpp.h文件
#include<iostream> using namespace std; class CHello { private: public: CHello(); ~CHello(); void Print_HelloWorld(); };
helloworld_cpp.cpp文件
#include "helloworld_cpp.h" void CHello::Print_HelloWorld() { cout << "Hello World!" << endl; } CHello::CHello() { } CHello::~CHello() { }
到这里,我们实际实现的内容都以及全部完成了。现在我们需要做一些改变以使得C能够调用到C++接口。下面我们再写个接口文件。
helloworld_interface.h文件,该文件提供给C语言使用,使得C语言能够调用C++的接口。需要调用该接口的代码,就需要包含此文件,例如下面的mian.c文件就包含了该文件。
#ifndef HELLOWORLD_INTERFACE_H #define HELLOWORLD_INTERFACE_H #ifdef __cplusplus extern "C"{ #endif void Print_HelloWorld(); #ifdef __cplusplus } #endif #endif //HELLOWORLD_INTERFACE_H
helloworld_interface.cpp文件,这个文件将C++的接口变成了C语言可以调用的接口。在这个文件中需要包含helloworld_cpp.h文件,因为它需要使用CHello这个类。但是不能在helloworld_interface.h文件包含,因为C语言需要包含helloworld_interface.h文件,否则会导致编译不过去。
#include "helloworld_interface.h" #include "helloworld_cpp.h" static CHello g_interface; void Print_HelloWorld() { g_interface.Print_HelloWorld(); }
至此,我们的C++文件就写完了,将其编译为动态链接库。使用的命令如下:
g++ -shared -fPIC helloworld_cpp.cpp helloworld_interface.cpp -o libhelloworld_cpp.so
编译之后,生成名为libhelloworld_cpp.so的动态链接库。将其拷贝一份到/usr/lib目录之下。
我们编译main.c文件来调用C++接口,其内容如下。
#include "helloworld_interface.h" int main() { Print_HelloWorld(); return 0; }
编译main.c文件,命令如下:
gcc main.c -o main -L. -lhelloworld_cpp
./main执行main,输出如下所示:
更多相关内容 -
vs2017 C++动态链接库的创建和调用(隐式)
2021-06-08 16:46:27vs2017 C++动态链接库的创建和调用,在VS2017下创建C++动态库(编译时去掉预编译头),把.h ,lib文件拷入新建测试工程目录下并添加到该工程中,dll文件加到运行目录下 -
C++动态链接库视频教程(Windows动态链接库)
2021-06-09 12:53:04动态链接库在企业级开发中无处不在,本课程包含Windows动态链接库相关知识点,通过浅显易懂的代码与讲解,让你熟悉掌握动态链接库技术! -
VS2019开发简单的C/C++动态链接库并进行调用的实现
2020-08-24 21:45:57主要介绍了VS2019开发简单的C/C++动态链接库并进行调用的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 -
C++ 动态链接库
2021-06-01 09:01:19C++ Lib和Dll的加载加载Dll1>通过LoadLibary加载, GetProcAddress调用 加载Dll 1>通过LoadLibary加载, GetProcAddress调用 如果加载失败,通过GetLastError()获取失败原因。 下面是LoadLibary的示例代码 第一...原创文章,转载请注明出处。
如果Windows系统有缺失的DLL文件,可以去这个链接下载。点击去这里寻找
C++ DLL简介以及使用
1>认识DLL(动态链接库)
动态链接库DLL(Dynamic-Link Library)通常包含程序员自定义的变量和函数, 可以在运行时动态链接到可执行文件(我们的exe程序)中。
2 >格式后缀
Windows上:(.dll)
Linux上:(.so)
Android上:(.so)
IOS上:(.dylib)3 >DLL优点
1)模块化,耦合小:大规模软件开发中,开发过程独立,耦合度小,比如UE4里面的模块(每一个.build.cs)都是一个DLL。
2)扩展性:DLL文件与EXE文件是独立的,只要接口不变,升级程序只需更新DLL文件不需要重新编译应用程序。并且我们的EXE文件较小。
3)复用性:DLL的编制与具体的编程语言以及编译器无关,不同语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数。
4)节省内存:当应用程序使用动态链接时,多个应用程序可以共享磁盘上单个DLL副本。
5)隐私性:可以当做黑盒使用,可以将我们的具体实现代码隐藏起来,比如我们想将算法的具体实现隐藏起来,不让别人看到我是怎么做的。一般SDK接入时候,里面的具体算法实现都是不会公开cpp的。
4 >DLL缺点
如果是动态loaddll的话,会牺牲部分性能吧。微乎其微的。
5 >加载DLL
1>动态加载(运行时加载)通过LoadLibary加载, GetProcAddress调用。
如果加载失败,通过GetLastError()获取失败原因。
下面是LoadLibary的示例代码
第一步,在.h中声明了static HMODULE hDLL;#include<Windows.h> //加载的头文件 class QIDCardReader : public QMainWindow { Q_OBJECT public: QIDCardReader(QWidget* parent = 0); private: static HMODULE hDLL; };
第二步,定义要调用的dll中的方法。并通过LoadLibrary给hDLL赋值
#include "QIDCardReader.h" //CPP中预声明一下我要调用dll里面的方法 typedef int(*MyRouton_RepeatRead)(bool); typedef int(*MyInitComm)(int); typedef int(*MyAuthenticate)(); typedef int(*MyReadBaseInfosPhoto)(char * , char * , char * , char *, char * , char * , char *, char * , char* , char * ); typedef int(*MyCloseComm)(); HMODULE QIDCardReader::hDLL; QIDCardReader::QIDCardReader(QWidget* parent) : QMainWindow(parent) ,ui_(new Ui::QIDCardReaderClass) { hDLL = LoadLibrary(L"D:\\bimvr-vrlauncher\\test\\Sdtapi.dll"); //加载dll文件 //如果加载失败的话, 通过GetLastError()进行获取,看失败原因。 auto code5 = GetLastError(); }
第三步,调用dll中的方法 GetProcAddress(hDLL, “实际的dll端函数导出名称”)
//调用1 if (hDLL) { MyRouton_RepeatRead MyRouton_RepeatReadFunc = (MyRouton_RepeatRead)GetProcAddress(hDLL, ("Routon_RepeatRead"));//直接使用原工程函数名 if (MyRouton_RepeatReadFunc) { MyRouton_RepeatReadFunc(true); } } //调用2 int iPort = 1001; //int ret = InitComm(iPort); int ret = -1000; if (hDLL) { MyInitComm MyInitCommFunc = (MyInitComm)GetProcAddress(hDLL, ("InitComm"));//直接使用原工程函数名 if (MyInitCommFunc) { ret = MyInitCommFunc(iPort); } } if (ret) { //ret = Authenticate(); if (hDLL) { MyAuthenticate MyAuthenticateFunc = (MyAuthenticate)GetProcAddress(hDLL, ("Authenticate"));//直接使用原工程函数名 if (MyAuthenticateFunc) { ret = MyAuthenticateFunc(); } } if (ret) { char user_name[31] = { 0 }; char user_gender[3] = { 0 }; char user_folk[11] = { 0 }; char user_birthday[9] = { 0 }; char user_code[19] = { 0 }; char user_address[71] = { 0 }; char user_agency[31] = { 0 }; char expire_start[9] = { 0 }; char expire_end[9] = { 0 }; QByteArray data_path = QString::fromStdWString(AppUtils::GetDataPath()).toLatin1(); ret = ReadBaseInfosPhoto(user_name, user_gender, user_folk, user_birthday, user_code, user_address, user_agency, expire_start, expire_end, str/*data_path.data()*/); if (hDLL) { MyReadBaseInfosPhoto MyReadBaseInfosPhotoFunc = (MyReadBaseInfosPhoto)GetProcAddress(hDLL, ("ReadBaseInfosPhoto"));//直接使用原工程函数名 if (MyReadBaseInfosPhotoFunc) { ret = MyReadBaseInfosPhotoFunc(user_name, user_gender, user_folk, user_birthday, user_code, user_address, user_agency, expire_start, expire_end, str/*data_path.data()*/); } } } }
第四步,可以选择性调用FreeLibrary(hDLL)卸载Dll,这个是下面的静态三件套加载方式做不到的。
也就是说我们可以动态控制Dll的加载与卸载。2>静态加载方式(.h .lib .dll三件套加载)
1>项目->属性->配置属性->VC++ 目录-> 在“包含目录”里添加头文件Sdtapi.h所在的目录
2>项目->属性->配置属性->VC++ 目录-> 在“库目录”里添加头文件Sdtapi.lib所在的目录
3>项目->属性->配置属性->链接器->输入-> 在“附加依赖项”里添加“Sdtapi.lib”(若有多个 lib 则以空格隔开)
也可以使用#pragma comment(lib, “Sdtapi.lib”)代替上面的1、2、3步骤。
QIDCardReader.cpp 包含.h,将.h添加到项目中#include "sdtapi.h" void QIDCardReader::onNotify() { Routon_RepeatRead(true); int iPort = 1001; int ret = InitComm(iPort); if (ret) { ret = Authenticate(); if (ret) { char user_name[31] = {0}; char user_gender[3] = {0}; char user_folk[11] = {0}; char user_birthday[9] = {0}; char user_code[19] = {0}; char user_address[71] = {0}; char user_agency[31] = {0}; char expire_start[9] = {0}; char expire_end[9] = {0}; QByteArray data_path = QString::fromStdWString(AppUtils::GetDataPath()).toLatin1(); ret = ReadBaseInfosPhoto(user_name, user_gender, user_folk, user_birthday, user_code, user_address, user_agency, expire_start, expire_end, data_path.data()); } } }
现在是可以通过编译了,但是运行会报错 提示LinkError
因为程序分为编译和链接两步骤,这就是为什么报错误的原因。
我们解决这个报错就是将.dll放到和.exe同级目录就好了如果最终exe找不到dll的话,会提示下面的错误。解决方法就是将dll放到和exe同级目录就好了。
谢谢,创作不易,大侠请留步… 动起可爱的双手,来个赞再走呗 <( ̄︶ ̄)> -
C++动态链接库的两种调用方式
2020-12-22 15:56:07动态链接库不能直接运行,也不能接收消息。它们是一些独立的文件,其中包含能被可执行程序或其它DLL调用来完成某项工作的函数或是数据。只有在其它模块调用动态链接库中的函数时,它才发挥作用。Windows API中的所有... -
C++ 动态链接库实现实例及解释
2015-05-13 11:46:24本实例是包括:求字符串长度的函数stringlen、字符串大小写转换函数stringupr、stringlwr及字符串比较函数stringcmp,在main函数中调用并输出结果。用动态链接方式实现,代码中有解释! -
Python调用C/C++动态链接库的方法详解
2020-12-24 22:10:01本文以实例讲解了Python调用C/C++ DLL动态链接库的方法,具体示例如下: 示例一: 首先,在创建一个DLL工程(本例创建环境为VS 2005),头文件: //hello.h #ifdef EXPORT_HELLO_DLL #define HELLO_API __declspec... -
C#调用C++动态链接库,函数为地址传递
2015-12-11 16:40:06c++编写的动态链接库,函数的参数为结构体地址,将结构体改为C#版本,使用C#调用dll,成功实例。 -
C#调用C++动态链接库示例
2022-04-09 10:34:52通过C#调用C++的动态链接库,示例中展示了多种在C#程序中调用C++动态链接库的情况,特别是对于各种类型参数的传递形式,并给出了哪些传递方式能成功。 -
浅析C/C++中动态链接库的创建和调用
2020-12-25 18:13:59下面为你介绍C/C++中动态链接库的创建和调用。 动态连接库的创建步骤: 创建Dll有两种方式。 一、创建Non-MFC DLL动态链接库 1、打开File —> New —> Project选项,选择Win32 Dynamic-Link Library —>sample ... -
C++动态链接库源码.zip
2022-04-03 22:50:45C++动态链接库源码.zip -
C++动态链接库编程深入浅出
2013-04-22 20:57:11C++动态链接库编程深入浅出,动态链接库的建立与调用。 -
C# 调用 c++ 动态链接库,浅学一下~
2022-04-25 01:19:03首先是c++动态库的生成,我这里最开始是没有选择动态链接库创建项目,从生成 .exe项目转换成 .dll 项目。改动两个地方项目属性——配置属性——常规——目标文件扩展名(改为 .dll)——配置类型(改为:动态库.dll)...- 用到了opencv,得安装opencv,不多叙述
- 首先是c++动态库的生成,我这里最开始是没有选择动态链接库创建项目,从生成 .exe项目转换成 .dll 项目。改动两个地方
项目属性——配置属性——常规——目标文件扩展名(改为 .dll)——配置类型(改为:动态库.dll)
如下图: - 详情代码 :
// dll 生成 c++ // .h #pragma once #include <opencv2\opencv.hpp> #include <iostream> using namespace std; using namespace cv; extern "C" _declspec(dllexport) void openImg(); // .cpp #include "ExternAPI.h" extern "C" _declspec(dllexport) void openImg() { string path = "D:/myProject/dog.png"; // 路径用'/'不用'\' 折磨~ Mat img = imread(path, 1); imshow("HUSKY_DOG", img); waitKey(0); destroyAllWindows(); } // c# 调用:把生成的.dll 文件拷贝至 c#生成的 .exe文件同级目录 using System; using System.Runtime.InteropServices; namespace CallDll { class Program { [DllImport("DoanOpencv.dll")] private extern static void openImg(); static void Main(string[] args) { Console.WriteLine("Test call CPlus DLL"); openImg(); Console.Read(); } } }
- 结果如下:
-
在Visual Studio中用C++语言创建DLL动态链接库图文教程
2020-09-04 03:26:11主要介绍了在Visual Studio中用C++语言创建DLL动态链接库图文教程,本文详细讲解了DLL库的创建过程,并给出了代码示例,需要的朋友可以参考下 -
深入浅出Visual_C++动态链接库(Dll)编程.pdf
2012-12-28 18:04:21深入浅出Visual_C++动态链接库(Dll)编程 讲的比较详细 -
VS创建和使用C++动态链接库教程
2022-03-19 17:59:43环境 系统:windows10 IDE:vs2005 创建 1.创建项目 打开vs,文件,新建项目,win32控制台...对于动态链接库,类和函数的格式: 导出函数 __declspec(dllexport) 返回值 函数名(参数列表); 导出类 class __declspe环境
系统:windows10
IDE:vs2005
创建
1.创建项目
打开vs,文件,新建项目,win32控制台应用程序,为项目起名
点击下一步,选择应用程序类型,dll,附加选项,空项目,点击完成2.编辑代码
用于测试的库包括一个函数一个类,函数实现计算阶乘的功能,类打印一个爱心。
对头文件夹右键点击,添加,新建项,选择头文件,起名字
对于动态链接库,类和函数的格式:
导出函数__declspec(dllexport) 返回值 函数名(参数列表);
导出类
class __declspec(dllexport) 类名;
编辑头文件abc.h,对函数和类进行声明
abc.h#pragma once __declspec(dllexport) int multiply(int); class __declspec(dllexport) cABC{ private: char symbol; public: cABC(char symbol); void print_love(); };
在源文件夹,添加一个cpp文件,实现功能
abc.cpp#include"abc.h" #include<stdio.h> int multiply(int number){ int ret=number; number--; for(;number>0;number--){ ret*=number; } return ret; } cABC::cABC(char symbol): symbol(symbol) { } void cABC::print_love(){ float y,x,a; for(y=1.5f;y>-1.5f;y-=0.1f){ for (x=-1.5f;x<1.5f;x+=0.05f){ a=x*x+y*y-1; putchar(a*a*a-x*x*y*y*y<=0.0f?symbol:' '); } putchar('\n'); } }
点击启动调试。会编译生成动态链接库,会弹出以下对话框,因为这不是一个应用程序,无法正常启动
对此
打开项目文件夹下的debug目录
会发现已经生成了相应的动态库文件libabc.dll。
同时又生成了一个.lib文件。对于.lib文件,通常是windows静态链接库文件。
实际上,这里的.lib文件不是静态链接库文件。这个.lib文件里有相应的.dll文件的名字和一个指明.dll文件中函数入口的顺序表。使用动态库编译程序时会使用到。
因此,动态库的dll文件,伴随的lib文件和相关的头文件是一起发行的
使用
1.创建项目
另外启动vs。新建一个项目
点击完成
2.编辑代码
将动态库的头文件abc.h拷贝到项目的源文件目录下
对头文件文件夹右键,添加,现有项,选择动态库头文件,添加
对源文件文件夹右键,添加,新建项,创建一个主程序源文件
编辑源文件,调用动态库中相关功能
main.cpp#include"abc.h" #include<windows.h> #include<iostream> int main(){ std::cout<<"5的阶乘是:"<<multiply(5)<<std::endl; std::cout<<"打印爱心:"<<std::endl; cABC abc('*'); abc.print_love(); system("pause"); return 0; }
3.添加lib文件
点击项目,属性,链接器,常规,附加库目录。将libabc项目生成的lib文件所在的目录添加进去
点击输入,附加依赖项,添加libabc生成的lib文件名称
点击启动调试,生成程序,之后会发现无法运行,因为系统找不到动态库libabc.dll
4.动态库文件使用
此时已经在testlib项目文件夹下生成了debug程序文件夹,将动态库libabc.dll拷贝到此文件夹下(系统会从程序运行目录下搜索动态库文件)
之后再次运行程序
-
linux下简单的制作一个C++动态链接库
2022-04-06 18:34:47} 打开终端输入: g++ dylib_test.cpp -fPIC -shared -o libdylib_test.so 来生成我们的动态库.so文件 然后在目录下:sudo cp libdylib_test.so /usr/lib/ 将我们的so文件拷贝到用户系统库里 再:sudo cp dylib_... -
C++动态链接库例子.zip
2021-04-16 15:37:13C++动态链接库封装C#调用示例 -
c#调用c++ 动态链接库
2017-06-08 15:09:52c#调用c++ 动态链接库 dll -
c++ 创建动态链接库dll并调用
2018-06-14 16:59:12本解决方案包含两个工程,一个是生成动态链接库dll(Mydll),一个工程test_mydll用于调用生成的动态链接库mydll.dll,适合初学者 -
基于java实现的c++动态链接库调用案例
2021-03-03 23:04:16基于java实现的c++动态链接库调用案例。该项目主要技术点就是有C++编写串口读写实现,以DLL动态链接库的形式提供接口,由java调用动态链接库接口实现串口消息发送。 -
C++编写DLL动态链接库的步骤与实现方法
2020-12-31 14:15:10本文实例讲述了C++编写DLL动态链接库的步骤与实现方法。分享给大家供大家参考,具体如下: 在写C++程序时,时常需要将一个class写成DLL,供客户端程序调用。这样的DLL可以导出整个class,也可以导出这个class的某个... -
C#调用C++动态链接库
2018-12-25 18:37:53将静态链接库做成动态链接库新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants... -
C++动态链接库的创建与使用
2014-08-15 18:54:07学习C++时的笔记,包括了C++动态链接库的创建与使用,还包括了C++中的调用约定等内容 -
c++ 动态链接库
2013-03-26 18:44:55c++ 动态链接库,包括传统方法,纯c方法导出函数和导出类,使用导出的类和MFC类,导入即用,不含糊! -
C++ 动态链接库和静态链接库
2019-09-23 15:59:58动态静态的区别静态链接库静态链接库的创建方法lib的调用动态链接库动态链接库的创建方法dll的使用隐式链接显式链接 源程序编译链接生成文件格式 首先贴出从源程序生成可执行文件的过程。 源程序(sour... -
如何使用JNA调用本地C/C++动态链接库详细示例代码
2011-07-22 15:24:34详细演示了如何通过JNA实现以下形式的动态链接库接口: 1:基本数据类型 2:基本数据类型的指针和引用 3:结构体 4:结构体的指针和引用 ...C++动态链接库; VC调用本地动态链接库; JNA调用本地动态链接库; -
C/C++动态链接库(dll)文件解析
2022-02-16 11:26:031.动态链接库(dll)概述 没接触dll之前觉得它很神秘,就像是一个黑盒子,既不能直接运行,也不能接收消息。它们是一些独立的文件,其中包含能被可执行程序或其他dll调用来完成某项工作的函数,只有在其他模块调用... -
C++动态链接库实例
2012-08-14 12:58:15便于在C#调用C++的动态链接库dll代码实例