zoukankan      html  css  js  c++  java
  • C++ dll的创建和使用

    在介绍Dll之前先了解下常见三种函数调用约定。

    参考:https://www.cnblogs.com/yejianyong/p/7506465.html

    我们使用的VS默认使用的函数调用约定是__cdel,而Windows API默认的调用约定是__stdcall。我们在使用一个dll的接口时,一定要确保你使用接口时的调用约定和接口定义时的调用约定一致。因为不同的调用约定,函数的栈内存释放的方式不同。

    然后我们再了解下extern C的作用,参考https://www.cnblogs.com/carsonzhu/p/5272271.html

    如果我们使用C++进行程序开发,开发过程中使用到了C语言写的库函数,则我们就需要使用extern C 来修饰,来告诉编译器,这部分代码使用C语言语法进行编译链接。

    例如:

    #ifdef __cplusplus

    extern "C" {

    #endif

    #include "legacy_C_header.h"

    #ifdef __cplusplus

    }

    #endif

    这个就是它允许你在你的C ++代码中使用这个C头文件,因为宏“__cplusplus”将被定义。

    下面我们开始学习C++Dll的创建和使用

    C++创建的dll既可以给C++工程使用也可以给C#工程使用。

    C++导出函数,在DLL中有一张导出表,记录着需要导出的函数,这些函数可供外部程序调用,即这些函数都是该DLL的入口点(类似main函数)。不在导出表中的函数,为该DLL私有的函数,外部程序不能调用它们。

    C++工程调用C++导出函数或者导出类

    导出函数的几个方法参考https://www.cnblogs.com/findumars/p/8660427.html

    在函数声明时,直接使用__declspec(dllexport)声明函数

    或者是直接使用def文件指定导出的函数

    使用导出函数库时,我们可以直接在VS上配置,指定库目录和动态库对应的lib文件名,以及C/C++常规中的包含目录,该目录指定头文件。

     

     

    也可以直接在代码中使用#pragma comment,具体语法可以参考https://blog.csdn.net/wfq_1985/article/details/7456591

    使用如下:

    #pragma comment(lib, "..\CplusplusDll\Debug\CplusplusDll.lib")

    当你不知道头文件只知道你使用的函数类型时,则可以使用如下函数:

    typedef int(*func)(int, int); 

    HINSTANCE hInstance = LoadLibrary(L"..\CplusplusDll\Debug\CplusplusDll.dll");

    LPCSTR pc = "?GetMax@@YAHHH@Z";

    func getmax = (func)GetProcAddress(hInstance, pc);

    int max = getmax(a, b);

    使用微软VS提供的dumpbin –exports xxx.dll 可以查看你的函数名,同时你一定要确保你的调用约定和GetMax函数定义的一致。这里使用的是func的约定使用默认值一般是__cdel,函数GetMax定义的地方也是__cdel。如果是__stdcall则需要显示声明{typedef int(__stdcall*func)(int, int);}

    注意,不建议直接使用这种方法对类的成员函数进行调用。

    对于C++导出类,C++工程在调用时和导出函数一致,除了不能使用LoadLibrary函数进行动态加载外,VS配置和#progma预编译指令都可以使用。

    #include "../CplusplusDll/CMath.h"

    #pragma comment(lib, "..\CplusplusDll\Debug\CplusplusDll.lib")

    CMath m;

    int sum = m.add(5, 6, 7);

    对于C#工程,如何调用C++导出函数呢?使用DllImport属性,在System.Runtime.InteropServices命名空间下定义。参考https://www.cnblogs.com/xingboy/p/11158487.html,使用如下

     [DllImport(@"CplusplusDll.dll",CallingConvention = CallingConvention.Cdecl,EntryPoint = "?GetMax@@YAHHH@Z")]

    public extern static int getMax(int a, int b);

    int a = getMax(2, 3);

    对于非托管的C++类,C#是无法直接使用,但是C#支持托管的C++代码的使用。所以非托管的C++类,可以通过托管类包装,进行导出,C++托管类使用的数据类型必须都是托管的,详情可以以下链接:https://blog.csdn.net/weixin_34167819/article/details/91974250

  • 相关阅读:
    SWT的TableVierer的使用二(数据排序)
    SWT的TableVierer的使用一
    SWT的TreeVierer的使用
    SWT中一些细节的说明
    SWT中各种参数大全
    SWT的GridLayout一些参数解释
    SWT中的GridLayout(转)例子不错
    鼠标放到按钮上,实现的动画
    关于文字下方线消失的动画
    超出部分用省略号代替,鼠标放上去显示多余部分内容
  • 原文地址:https://www.cnblogs.com/merlinzjl/p/11795857.html
Copyright © 2011-2022 走看看