精华内容
下载资源
问答
  • vs2010 创建和使用动态链接库 (dll) 1打开 Microsoft Visual Studio 2010 选择 File->New->Project 2在 New Project 中选择 Installed Templates->Visual C++->Win32 3选择 Win32 Console Application ...
  • 众所周知,python调用dll动态链接库极其简单,加载一下dll...那么Java是怎么调用dll动态链接库的呢? 大概分为以下几步: 1.创建Java类,在该类中加载dll文件,再该类生成xxx.h文件 2.创建xxx.c文件,引用xxx...

    众所周知,python调用dll动态链接库极其简单,加载一下dll文件,就可以调用其中的方法。那么目前仍热火朝天的Java能不能调用dll库,使用其中的方法呢?当然是可以的,但是相对于python来讲是稍微有一点困难。

    那么Java是怎么调用dll动态链接库的呢?

    大概分为以下几步:

    1.创建Java类,在该类中加载dll文件,再用该类生成xxx.h文件

    2.创建xxx.c文件,引用xxx.h头,实现xxx.h中的方法。

    还有信心继续下去嘛?听着有点头大?又是h文件又是头文件的,糟心!别慌,准备一包瓜子咱们来调用dll中的一个实战一波你就明白了,下边我们实现一个Java调用dll中方法,实现两个数相加并返回控制台输出的简单案例。

    1、先创建Java类,我这里创建了一个ConnectDll类(包名我也复制下来了)。

    package com.csdn.dll;
    
    public class ConnectDll {
        static {
            System.loadLibrary("");
        }
        public static native int add(int num1,int num2);
    }

    2.编译此类,生成对应的.class文件。

    什么?不会生成?请自行百度javac命令。

    3.将.class文件编译成 .h头文件。

    很多人到这里就懵了,java文件还能转成.h文件么?是的,利用javah命令,可以将class字节码文件转换成.h文件。

    众所周知,我们写项目,一般会在src下写很多级包名,然后在包里边写各个类,从上面的代码可以看出,我的包名为com.csdn.dll。但是我们生成项目文件的时候,系统会自动地把包名转换成各级文件夹。如果用javac命令将.java文件编译成class文件,需要进入到java文件所在的文件夹,但是用javah命令,只需要到包的上一级,即src目录下即可。然后用javah命令 +包名+类名。

    具体命令: javah com.csdn.dll.ConnectDll  (因为ConnectDll类的包名是com.csdn.dll)。

    生成的.h文件就在src目录下。

    4.让我们一窥.h文件的究竟。

    学过C语言的都知道h是头文件,所以我认为h文件相当于Java的接口,C文件相当于java的实现类。(由于我C语言比较差,这里可能不太准确,如有大佬看到,请及时评论纠正。),下面是h文件中的东西,让我们一起看看。

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_csdn_dll_ConnectDll */
    
    #ifndef _Included_com_csdn_dll_ConnectDll
    #define _Included_com_csdn_dll_ConnectDll
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_csdn_dll_ConnectDll
     * Method:    add
     * Signature: (II)I
     */
    JNIEXPORT jint JNICALL Java_com_csdn_dll_ConnectDll_add
      (JNIEnv *, jclass, jint, jint);
    
    #ifdef __cplusplus
    }
    #endif
    #endif

     

    从这个头文件中我们可以看到存在这样一个方法

    JNIEXPORT jint JNICALL Java_com_csdn_dll_ConnectDll_add(JNIEnv *, jclass, jint, jint);

    对比一下我们在ConnectDll类中写的方法

    public static native int add(int num1,int num2);

    我们可以发现一些东西还是比较相似的。如:jint   ----->>int。

    5.编写对应的实现文件C文件,生成dll库。

    到了这里,我不知道大家是否还记得我们的初衷?我们的初衷是想用java调用dll文件,但是我们写了半天了也没见dll文件的生成以及调用啊?(之前接触过C的大佬可能知道,但是对于C语言本身就不怎么样的我来说,生成dll难为了我半天。)

    以下内容C语言大佬可以自动忽略

    如何生成dll文件?

    我这里的工具是DevC++。(觉得Dev麻烦的可以忽略,然后自行百度其他软件生成dll)

    1.打开Dev,文件->新建->项目,选择DLL项目,C语言,项目名称。

    2.创建完项目,如下

    3.将h和C文件书写完整保存,编译一下,就能在该项目目录中找到dll文件。

    根据java生成的h文件,生成dll库并调用其中方法。

    我们知道了如何生成dll文件,但是这跟我们java生成的.h文件又有什么关系呢?通过上面我们可以看到dll动态链接库实际上就是.h和.c编译链接生成的,我们通过dll文件可以调用dll中实现的方法。还是很混乱对吧,别急,我们先做,做完再回过头来看。

    我们通过javah生成了.h文件,将生成的.h文件复制到这个项目中,并写对应的.c文件。H文件内容上边已给,C文件如下,

    注意我这里引用的h文件是dll.h,我是把生成的h文件的内容复制到了dll.h下,文件内容如下:

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_csdn_dll_ConnectDll */
    
    #ifndef _Included_com_csdn_dll_ConnectDll
    #define _Included_com_csdn_dll_ConnectDll
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_csdn_dll_ConnectDll
     * Method:    add
     * Signature: (II)I
     */
    JNIEXPORT jint JNICALL Java_com_csdn_dll_ConnectDll_add
      (JNIEnv *, jclass, jint, jint);
    
    #ifdef __cplusplus
    }
    #endif
    #endif

    这是C文件,文件内容如下

    /* Replace "dll.h" with the name of your header */
    #include "dll.h"
    #include <windows.h>
    
    JNIEXPORT jint JNICALL Java_com_csdn_dll_ConnectDll_add(JNIEnv * env, jclass cls, jint i, jint j){
    	return i+j;
    } 

    点击编译,一般是会报错的,原因是没有 <jni.h>头文件。自行百度解决。

    编译完成后,发现dll项目文件中多了一个后缀为.dll文件。这个就是我们要的。

    6.Java文件加载Dll文件

    在我们最开始的ConnectDll类中,有这么一段代码,System.loadLibrary("");这就是加载dll文件的代码,修改成这样System.loadLibrary("ConnectDll");(因为我的dll文件是ConnectDll.dll。)

    7.编写Java测试类调用此方法

    package com.csdn.test;
    
    import com.csdn.dll.ConnectDll;
    
    public class Test {
        public static void main(String[] args) {
            System.out.println(ConnectDll.add(3,5));
    
        }
    }

    运行,会出现一堆错误,是因为你系统找不到你说的这个dll文件,怎么办呢?把这个dll文件放入JDK/bin目录中可以解决。

    但是我们不能只知其然不知其所以然,System.loadLibrary("");这行代码的意思就是加载文件,但是它加载的是环境变量下的文件,系统会查找环境变量下有没有这个文件。当然加载文件还有一个方法System.load("");这个方法是加载绝对路径的文件。

    8.综上所述

    1.创建Java类

    2.编译生成h头文件

    3.实现头文件中的方法并生成dll

    4.设置Java类中文件加载地址

    9.展望

    我们是Java开发者,我们不太可能会自己直接编写dll文件,一般都是调用别人写好的dll文件。我们可以自己编写一个dll文件来调用别人写好的dll,但是无论怎样都太过繁琐。我们程序员应该有一种精神叫"懒",我们接受不了这种太过复杂的调用,这样开发太过于繁琐。所以我们应该想着有没有什么简单的方式,可以直接在java中调用,像python那样。在写此文章的时候,搜到了其他解决方案,JNA和JNative,可以简化开发。

     

     

    展开全文
  • MFC调用DLL动态链接库

    2013-08-22 03:11:36
    MFC制作了一个DLL动态链接库,然后另外一个MFC程序区调用它,但是没有效果。其程序如下: 制作一个MFC生成DLL程序,改DLL内部封装了一个函数。如下(.cpp文件): int sum(int a,int b) { char temp[200...
  • 1.对于Dll文件,字面上的意思是动态链接库。可是,动态链接库,又是什么呢? 回答这个问题前,先需要说明下,Dll只是动态链接库的其中一种,不是说动态链接库只有DLl。 2.动态链接库是什么?动态链接库,就是将很多...

    1.对于Dll文件,字面上的意思是动态链接库。可是,动态链接库,又是什么呢?
    回答这个问题前,先需要说明下,Dll只是动态链接库的其中一种,不是说动态链接库只有DLl。

    2.动态链接库是什么?动态链接库,就是将很多很多函数集合在一块,进而形成库文件,最后,将这些库文件进行共享给需要的人或者组织使用。这,就是动态链接库了。
    那么,既然知道了动态链接库是个什么东西后,自然而然,也许会有人询问,动态链接库该怎么用?

    3.首先,动态链接库的调用,有静态调用与动态调用。其次,它们都有着相应的使用方向与范围,各有千秋;最后,动态链接库,可以理解成是一种封装,然后无论是静态调用,抑或是动态调用,其实就是对这种经过封装好的函数,直接调用即可。
    这样做的好处,不仅可以简化代码,而且,还可以对代码进行重构,与拓展新的函数,看到这里,是不是觉得,动态链接库,非常的好了。相信,看到这里,对动态链接库有了个了解了。

     

    介绍:
    DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中。当我们执行某一个程序时,相应的DLL文件就会被调用。一个应用程序可使用多个DLL文件,一个DLL文件也可能被不同的应用程序使用,这样的DLL文件被称为共享DLL文件。[1]

    意义:
    DLL文件中存放的是各类程序的函数(子过程)实现过程,当程序需要调用函数时需要先载入DLL,然后取得函数的地址,最后进行调用。使用DLL文件的好处是程序不需要在运行之初加载所有代码,只有在程序需要某个函数的时候才从DLL中取出。另外,使用DLL文件还可以减小程序的体积。

    优点:
    (1) 更加节省内存并减少页面交换;

    (2) DLL文件与EXE文件独立,只要输出接口不变(即名称、参数、返回值类型和调用约定不变),更换DLL文件不会对EXE文件造成任何影响,因而极大地提高了可维护性和可扩展性;

    (3) 不同编程语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数;

    (4)适用于大规模的软件开发,使开发过程独立、耦合度小,便于不同开发者和开发组织之间进行开发和测试。

    (5)节约磁盘空间:当应用程序使用动态链接时,多个应用程序可以共享磁盘上单个DLL副本。相比之下,当应用程序使用静态链接库时,每个应用程序要将库代码作为独立的副本链接到可执行镜像中。

    缺点:
    使用动态链接库的应用程序不是自完备的,它依赖的DLL模块也要存在,如果使用载入时动态链接,程序启动时发现DLL不存在,系统将终止程序并给出错误信息。而使用运行时动态链接,系统不会终止,但由于DLL中的导出函数不可用,程序会加载失败;速度比静态链接。当某个模块更新后,如果新模块与旧的模块不兼容,那么那些需要该模块才能运行的软件,统统死掉。
     

     


     

    展开全文
  • C#调用YOLOv3算法dll动态链接库(YOLO算法落地)

    千次阅读 热门讨论 2020-08-01 16:26:18
    C#调用YOLOv3算法dll动态链接库 前段时间在搞一个软件,目标是实现细胞计数的功能,当时我细胞计数的算法用到的是YOLOv3目标检测算法,所以就涉及到怎么实现模型落地的问题。当时有个同学在帮老师做项目,他比较懂,...

    C#调用YOLOv3算法dll动态链接库

    前段时间在搞一个软件,目标是实现细胞计数的功能,当时我细胞计数的算法用到的是YOLOv3目标检测算法,所以就涉及到怎么实现模型落地的问题。当时有个同学在帮老师做项目,他比较懂,我于是向他寻求帮助,但是…可能涉及到了商业机密吧,于是我就自己研究。
    我看了很多博客,感觉讲的也不是很到位,或者说没有给出一些干货,今天我来给大家带点干货,当然我是用**C#**调用的YOLOv3动态链接库,如果有需要的小伙伴就拿去吧。

    yolov3编译成动态库

    大家按照这个链接去GitHub下载YOLOv3的源码:https://github.com/AlexeyAB/darknet?tdsourcetag=s_pcqq_aiomsg.我是按照这个教程做的:https://zhuanlan.zhihu.com/p/97605980,这个教程还是很详细的,我就不讲了。

    C#调用YOLOv3动态链接库

    我已经将软件打包到GitHub上了:https://github.com/NameZth/AICounter-master.git,由于YOLOv3的权重文件和配置文件太大就没有上传,所以需要小伙伴自己训练一下模型. 当然我也是参考别人做的:https://github.com/RaminAbbaszadi/YoloWrapper-WPF,下面是文件的分布:
    在这里插入图片描述在***DeepLearningWrapper***这个文件中调用的YOLOv3的动态链接库:

    using System;
    using System.IO;
    using System.Text;
    using System.Linq;
    using DeepLearning.Base;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    
    namespace DeepLearning
    {
        public class DeepLearningWrapper : IDisposable
        {
            #region Const
    
            public const int MAX_OBJECTS_NUMBER = 1000;
            private const string DEEP_LEARNING_LIBRARY_DLL_CPU_VERSION = @"\x64\yolo_cpp_dll.dll";
            private const string DEEP_LEARNING_LIBRARY_DLL_GPU_VERSION = @"\x64\yolo_cpp_gpu.dll";
    
            #endregion
    
            #region Fields
    
            private static Dictionary<int, string> m_ObjectType = new Dictionary<int, string>();
            private static NetConfigaration m_NetConf;
    
            #endregion
    
            #region Initilizing
    
            public DeepLearningWrapper()
            {
            }
    
            #endregion
    
            #region DllImport Cpu
    
            [DllImport(DEEP_LEARNING_LIBRARY_DLL_CPU_VERSION, EntryPoint = "init")]
            public static extern int InitializeNetInCpu(string configrationFilenamr, string weightFileanme, int gpu);
    
            [DllImport(DEEP_LEARNING_LIBRARY_DLL_CPU_VERSION, EntryPoint = "detect_image")]
            internal static extern int DetectImageInCpu(string filename, ref BoundingBoxContainer container);
    
            [DllImport(DEEP_LEARNING_LIBRARY_DLL_CPU_VERSION, EntryPoint = "detect_mat")]
            internal static extern int DetectImageInCpu(IntPtr pArray, int nSize, ref BoundingBoxContainer container);
    
            [DllImport(DEEP_LEARNING_LIBRARY_DLL_CPU_VERSION, EntryPoint = "dispose")]
            internal static extern int DisposeNetInCpu();
    
            #endregion
    
            #region DllImport Gpu
    
            [DllImport(DEEP_LEARNING_LIBRARY_DLL_GPU_VERSION, EntryPoint = "init")]
            internal static extern int InitializeNetInGpu(string configurationFilename, string weightsFilename, int gpu);
    
            [DllImport(DEEP_LEARNING_LIBRARY_DLL_GPU_VERSION, EntryPoint = "detect_image")]
            internal static extern int DetectImageInGpu(string filename, ref BoundingBoxContainer container);
    
            [DllImport(DEEP_LEARNING_LIBRARY_DLL_GPU_VERSION, EntryPoint = "detect_mat")]
            internal static extern int DetectImageInGpu(IntPtr pArray, int nSize, ref BoundingBoxContainer container);
    
            [DllImport(DEEP_LEARNING_LIBRARY_DLL_GPU_VERSION, EntryPoint = "dispose")]
            internal static extern int DisposeNetInGpu();
    
            [DllImport(DEEP_LEARNING_LIBRARY_DLL_GPU_VERSION, EntryPoint = "get_device_count")]
            internal static extern int GetDeviceCount();
    
            [DllImport(DEEP_LEARNING_LIBRARY_DLL_GPU_VERSION, EntryPoint = "get_device_name")]
            internal static extern int GetDeviceName(int gpu, StringBuilder deviceName);
    
            #endregion
    
            #region Dispose
    
            public void Dispose()
            {
                switch (DetectionHardware)
                {
                    case DetectionHardwares.CPU:
                        DisposeNetInCpu();
                        break;
                    case DetectionHardwares.GPU:
                        DisposeNetInGpu();
                        break;
                }
            }
    
            #endregion
    
            #region Wrapper
    
            public void InitilizeDeepLearningNetwork(int gpu = 0)
            {
                if (m_NetConf == null)
                    m_NetConf = new NetConfigaration();
    
                HardwareReport = new HardwareReports();
    
                DetectionHardware = DetectionHardwares.CPU;
                if (HardwareReport.IsCudaExists && HardwareReport.IsCudnnExists)
                    DetectionHardware = DetectionHardwares.GPU;
    
                switch (DetectionHardware)
                {
                    case DetectionHardwares.CPU:
                        InitializeNetInCpu(m_NetConf.ConfigFile, m_NetConf.Weightfile, 0);
                        break;
                    case DetectionHardwares.GPU:
                        var deviceCount = GetDeviceCount();
                        if (gpu > (deviceCount - 1))
                            throw new IndexOutOfRangeException("Graphic device index is out of range");
                        var deviceName = new StringBuilder();
                        GetDeviceName(gpu, deviceName);
                        HardwareReport.GraphicDeviceName = deviceName.ToString();
                        InitializeNetInGpu(m_NetConf.ConfigFile, m_NetConf.Weightfile, gpu);
                        break;
                    default:
                        break;
                }
    
                var lines = File.ReadAllLines(m_NetConf.NamesFile);
                for (var i = 0; i < lines.Length; i++)
                    m_ObjectType.Add(i, lines[i]);
            }
    
    
            public IEnumerable<DetectedItemInfo> Detect(string imageFilePath)
            {
                if (!File.Exists(imageFilePath))
                    throw new FileNotFoundException("Cannot find the file", imageFilePath);
    
                var container = new BoundingBoxContainer();
                var count = 0;
                switch (DetectionHardware)
                {
                    case DetectionHardwares.CPU:
                        count = DetectImageInCpu(imageFilePath, ref container);
                        break;
                    case DetectionHardwares.GPU:
                        count = DetectImageInGpu(imageFilePath, ref container);
                        break;
                }
    
                return Convert(container);
            }
    
            public IEnumerable<DetectedItemInfo> Detect(byte[] imageData)
            {
                var container = new BoundingBoxContainer();
    
                var size = Marshal.SizeOf(imageData[0]) * imageData.Length;
                var pnt = Marshal.AllocHGlobal(size);
    
                try
                {
                    // Copy the array to unmanaged memory.
                    Marshal.Copy(imageData, 0, pnt, imageData.Length);
                    var count = 0;
                    switch (DetectionHardware)
                    {
                        case DetectionHardwares.CPU:
                            count = DetectImageInCpu(pnt, imageData.Length, ref container);
                            break;
                        case DetectionHardwares.GPU:
                            count = DetectImageInGpu(pnt, imageData.Length, ref container);
                            break;
                    }
                }
                catch (Exception exception)
                {
                    return null;
                }
                finally
                {
                    // Free the unmanaged memory.
                    Marshal.FreeHGlobal(pnt);
                }
    
                return Convert(container);
            }
    
            #endregion
    
            #region Utilities
    
            private IEnumerable<DetectedItemInfo> Convert(BoundingBoxContainer container)
            {
                var netItems = new List<DetectedItemInfo>();
                foreach (var item in container.candidates.Where(o => o.height > 0 || o.width > 0))
                {
                    var objectType = m_ObjectType[(int)item.obj_id];
                    var netItem = new DetectedItemInfo() { X = (int)item.leftTopX, Y = (int)item.leftTopY, Height = (int)item.height, Width = (int)item.width, Confidence = item.prob, Type = objectType };
                    netItems.Add(netItem);
                }
    
                return netItems;
            }
    
            #endregion
    
            #region Properties
    
            public DetectionHardwares DetectionHardware = DetectionHardwares.Unknown;
            public HardwareReports HardwareReport { get; private set; }
    
            #endregion
        }
    }
    
    

    然后就是在其他软件中类的定义:
    ***BoundingBox***文件:

    using System;
    
    namespace DeepLearning
    {
        internal struct BoundingBox
        {
            #region Fields
    
            internal UInt32 leftTopX, leftTopY, width, height;
            internal float prob;
            internal UInt32 obj_id;
            internal UInt32 track_id;
            internal UInt32 frames_counter;
            
            #endregion
        }
    }
    
    

    ***BoundingBoxContainer***文件:

    using System.Runtime.InteropServices;
    
    namespace DeepLearning
    {
        [StructLayout(LayoutKind.Sequential)]
        internal struct BoundingBoxContainer
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DeepLearningWrapper.MAX_OBJECTS_NUMBER)]
            internal BoundingBox[] candidates;
        }
    }
    
    

    ***DetectedItemInfo***文件:

    namespace DeepLearning
    {
        public class DetectedItemInfo
        {
            #region Properties
    
            public string Type { get; set; }
            public double Confidence { get; set; }
            public int X { get; set; }
            public int Y { get; set; }
            public int Width { get; set; }
            public int Height { get; set; }
    
            #endregion
    
            #region Utilities
    
            public bool Compare(DetectedItemInfo newItem)
            {
                bool result = false;
                if (newItem != null)
                {
                    if (newItem.Type == this.Type && newItem.Confidence == this.Confidence &&
                        newItem.X == this.X && newItem.Y == this.Y && newItem.Width == this.Width &&
                        newItem.Height == this.Height)
                    {
                        result = true;
                    }
                }
                return result;
            }
    
            #endregion
        }
    }
    HardwareReports文件:
    using System;
    using System.IO;
    
    namespace DeepLearning
    {
        public class HardwareReports
        {
            #region Initilizing
    
            public HardwareReports()
            {
                Init();
            }
    
            private void Init()
            {
                if (File.Exists(@"x64\cudnn64_7.dll"))
                   IsCudnnExists = true;
    
                var envirormentVariables = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Machine);
                if (envirormentVariables.Contains("CUDA_PATH"))
                    IsCudaExists = true;
    
            }
    
            #endregion
    
            #region Properties
    
            public bool IsCudaExists { get; set; }
            public bool IsCudnnExists { get; set; }
            public string GraphicDeviceName { get; set; }
    
            #endregion
        }
    }
    

    NetConfigaration文件:

    namespace DeepLearning
    {
        public class NetConfigaration
        {
            #region Const
    
            private const string CONFIG_FILE_PATH = @"Assets\Aalskidhytd.cfg";
            private const string WEIGHT_FILE_PATH = @"Assets\Aalskidhytd.weights";
            private const string NAMES_FILE_PATH  = @"Assets\Aalskidhytd.names";
    
            #endregion
    
            #region Initilizing
    
            public NetConfigaration()
            {
                Init();
            }
    
            private void Init()
            {
                ConfigFile = CONFIG_FILE_PATH;
                Weightfile = WEIGHT_FILE_PATH;
                NamesFile  = NAMES_FILE_PATH;
            }
    
            #endregion
    
            #region Properties
    
            public string ConfigFile { get; set; }
            public string Weightfile { get; set; }
            public string NamesFile { get; set; }
    
            #endregion
        }
    }
    
    

    软件界面展示(检测的精度不是很高):
    在这里插入图片描述

    展开全文
  • VC++ DLL 3 动态链接库

    2019-09-03 23:20:56
    前面先介绍了静态链接库的方式提供了函数结构的方法,现在就来说下,如果非MFC的动态链接库怎么实现,这个过程稍微复杂一点点,但是基本也都是一个套路下来。 1、新建一个工程: 2、编写cpp文件和头文件...

    前面先介绍了静态链接库的方式提供了函数结构的方法,现在就来说下,如果用非MFC的动态链接库要怎么实现,这个过程稍微复杂一点点,但是基本也都是一个套路下来。

    1、新建一个工程:

    2、编写cpp文件和头文件,这里有两种方式:

    (1)、新建工程之后会有相应的cpp文件,可以直接在cpp文件中编写:

    (2)、新建新的.h/.cpp文件进行编写:

     

    3、编译生成lib文件和dll文件:

    4、新建调用工程:

    这里要注意几点:

    (1)、typedef int(*lpAddFun)(int, int);宏定义函数指针类型,该定义是与将要调用函数的形式一样的,也就是输入参数和返回值都要一样,函数名称可以不同;

    (2)、hDll = LoadLibrary(L"noMFCdllSrc.dll");是加载dll文件进来,一定要注意L"noMFCdllSrc.dll"前面有个大写的L,不加这个的话会报错,涉及到const char*跟LP LPCWSTR数据类型的转换问题,函数返回值的类型如下:

    (3)、addFun = (lpAddFun)GetProcAddress(hDll, "add");获取函数add在dll文件中的地址;

    (4)、使用完函数之后记得调用FreeLibrary来释放内存;

    (5)、使用dll只需要将相关的dll文件放置在工程调用到的位置即可,不需要将.h文件和.lib文件一起拷贝过来;

    (6)、如果需要在调用的工程中进入函数调试的话,暂时不知道;

    (7)、DLL内的函数分为内部函数和外部函数,内部函数是无法通过调用dll来给外部使用,只能是dll内部使用,因此,要提供给外部使用的话,需要在函数声明处添加__declspec(dllexport),前面是两个下划线,即可声明为导出函数。

    5、声明DLL的另一种方式是采用模块定义(.def)文件声明,.def文件为连接器提供了关于被链接程序的导出、属性和其他方面的信息,需要在dll工程中添加.def文件:

    (1)、声明def文件:

    def文件规则:

        a、LIBRARY语句声明了.def文件对应的dll文件;

        b、EXPORT语句后面跟随的是导出函数名,导出函数名后面的@数字表示导出函数的序号,在调用函数的时候可以用;

        c、def文件中的注释由每个注释行开始处的分号指定,并且注释不可以和代码语句同一行。

    (2)、调用,通过def文件定义后,要调用dll的方式跟基本前面一样的但是在获取函数地址的时候要通过下面这种方式来获取:

    这一步我应该是没有尝试的,后面有尝试的话再来更新。

    6、DLL的调用分为动态调用和静态调用:

    (1)、动态调用,前面的方式都属于动态调用,就是三个步骤:“LoadLibrary-GetProcAddress-FreeLibrary”;

    (2)、静态调用:编译系统完成对dll的加载,应用程序结束完成对DLL的卸载,也就是说调用dll的应用程序的数量系统中有记录,每结束一个计数减一直到调用dll的所有应用程序都结束了,才释放。静态调用需要将dll文件和lib文件一起使用不需要修改编写dll的程序,只是调用dll的程序需要修改调用方式:

    其中,语句含义如下:    

    #pragma comment(lib, "noMFCdllSrc.lib") //同前面静态链接库的链接方式一样
    
    extern "C" int __declspec(dllimport)add(int, int); //则是声明导入函数;

    静态调用的过程:在工程中导入lib文件,在应用程序中,lib文件将作为DLL的替代文件参与编译;然后声明导入函数,调用。

    7、dll函数的入口DLLMain函数

    提供dll的时候并没有提供DllMain函数,系统会引入一个不做任何操作的缺省DllMain函数,但是在编写dll的时候,DllMain还是必须的;DllMain不能被引用,只能被系统加载和卸载dll、单个线程启动或者终止的时候自动调用;

    函数输入:

    APIENTRY是宏定义#define APIENTRY WINAPI

    而WINAPI则是宏定义#define WINAPIV __cdecl,这表示函数以标准Pascal的方式调用

    win32中,HMODULE的值和HINSTANCE一样,进程中每个dll模块都被全局唯一的32字节的HINSTANCE句柄标识,只有在特定的进程内部有效,并且,这个HINSTANCE代表了dll模块在进程虚拟空间中的起始位置。

    8、__stdcall声明

    VC++编写的程序要被其他语言调用,必须将函数的调用方式声明为__stdcall,WINAPI都采用这种方式;但是C/C++默认是__cdecl,这两种方式生成的符号不同:采用C编译的时候,__stdcall调用约定在函数名前加下划线,后加@数字,如”_add@1”;但是,__cdecl声明的只在前面加下划线,如”_add”;

     

    所以,如果在dll中声明为int __stdcall add(int x, int y);的话,在调用的时候就要声明为typedef int(__stdcall *lpAddFun)(int, int);否则会报错。

    大概就写到这里,这里还有导出变量和类的做法,还没有尝试,就先不写了,后面有尝试的话会补上的。

    春风动春心,流目瞩山林。

    山林多奇采,阳鸟吐清音。

      -- 佚名 《子夜四时歌·春风动春心》

     

     

     

     

     

    展开全文
  • 在工作过程中,需要用Teigha将CAD的一些基本操作嵌入到一个程序中,但是我们只有C#的TD_Mgd_3.03_9.dll,而之前的工程是用C++做的,所以涉及到怎么用C++语言调用C#生成的dll。这里就不讲CAD的二次开发是个什么东西,...
  • 动态链接库的使用与导出,以及如何dump看一个dll有哪些接口函数。以及怎样将自己创建的dll给别人使用
  • 动态链接库的概念(个人理解): 1.它是给其他程序调用的函数库 2.它被使用时,系统中仅有一份代码在内存中,即使有多个程序在使用它. 3.其他程序使用动态链接库时,"行为人"属于调用方,也就是说报错追责和动态库没关系,不...
  • MFC制作了一个DLL动态链接库,然后另外一个MFC程序区调用它,但是没有效果。其程序如下: 制作一个MFC生成DLL程序,改DLL内部封装了一个函数。如下(.cpp文件): int sum(int a,int b) { char temp[200];...
  • 为什么要用DLL? 答: 1:你选择用来开发的编程语言并不被Unity支持(如 F#),这个时候你就可以考虑把这样的代码编译成DLL文件。 2:你并不想让代码公开,只是想提供调用接口,那么DLL是一个很好的选择。 怎么...
  • win2000启动时提示“无法定位程序输入点SaferCreateLevel于动态链接库ADVAPI32.dll上”怎么解决?谢谢 悬赏分:5 - 解决时间:2006-5-10 20:24问题补充:win2000 一开机就出显这种情况,好像是每要指行某种程序的...
  • 最便捷的方法还是编写批处理命令(.bat),下面说说怎么创建这个批处理命令: 1、在桌面新建一个记事本文档(文本文档),重命名为 qtdll.bat 。 2、右键单击,点击编辑选项,或者记事本打开。 3、写入如下两...
  • 为什么要用DLL? 答:  1:你选择用来开发的编程语言并不被Unity支持(如 F#),这个时候你就可以考虑把这样的代码编译成DLL文件。  2:你并不想让代码公开,只是想提供调用接口,那么DLL是一个很好的...
  • 动态链接库入门

    2013-01-17 19:17:21
    动态链接库初探  这几天由于项目原因,初次接触动态链接库,后在网上查了下,了解到要深入理解动态链接库(涉及到反射机制等),要花很大的精力,里面的水很深!故作为初学者,我也只是略微学习下基础的要的操作,...
  • 上一篇对dll链接使用进行了粗略介绍,这一篇就以Opencv为例子介绍下怎么使用第三方来进行程序开发。Opencv是世界机器视觉领域非常著名的开源,里面包含了大量的图形处理算法,变换算法,匹配算法,也包括现在...
  • 2.怎么调用动态链接库,在项目里添加不进去尝试了如下代码 ``` //fcApi.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; ...
  • VB调用C++动态链接库

    2015-06-14 11:45:19
    现在有个C++动态链接库,有头文件,但是我想在VB里面调用。怎么在VB里面调用啊、麻烦帮忙把下面的3个函数转成能在VB里面的语句。 之前没接触过VB,现在因为时间紧,需要临时突击下。麻烦帮忙解答下啊。 #ifndef ...
  •  首先我介绍一下本项目所要解决的技术问题:项目是要求JAVA来调用delphi提供的动态链接库,而且硬件厂商已经提供了库以及接口文档.由于以前没有接触过这样的问题,所以考虑到要跟硬件设备打交道,
  • win32汇编动态链接库的编写及使用

    千次阅读 2016-05-30 21:53:32
    下面就来介绍一下动态链接库以及怎么使用动态链接库(以下简称DLL)。 当你编写一个程序的时候,为了使用以前写好的库中的函数,很方便的一个解决方法就是使用动态链接库DLL),下面我们先来编
  • 要编写自己的动态链接库首先需要创建一个dll工程,我的是win10+vs2015 创建dll工程后vs会自动给你生成几个文件。在Dll2.h和Dll2.cpp中写自己的类定义和类函数实现就好了。但是因为是要导出类所以要有__declspec...
  • 在运行时调用动态链接库 VS2010示例

    千次阅读 2016-12-14 16:56:12
    这里不再介绍动态链接库概念等知识,纯粹新建一个项目用来表述怎么在运行时调用动态链接库,代码中会给出相关注释。开发工具的是VS2010旗舰版。 一、创建动态链接库项目: 1.新建项目——选择Win32项目,...
  • 许多应用程序被分割成一些相对独立的动态链接库,放置于系统中,就产生了DLL文件。 ②DLL文件是什么 DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。在Windows中,许多...
  • C++对动态链接库的编写和调用

    千次阅读 2013-08-28 12:32:23
    之前遇到要C++编写一个动态链接库(Dynamic Link Library, dll)的问题,因为自从之前编写过一个Java调用的dll之后就没怎么再碰dll了(况且Java的JNI极大地简化了dll的开发),所以这次必须得查了一些文档才成功...
  • C++ 动态库怎么创建以及调用?

    千次阅读 2019-06-18 11:07:02
    在仓库的发展史上经历了“无库-静态链接库-动态链接库”的时代。目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入...
  • 今天QT编译生成的共享库自己却怎么都不能调用...Qt如何调用VC++生成的动态链接库?假设当前有VC++编译器生成的动态库文件testdll.h,testdll.lib和testdll.dll。 testdll.h文件源码如下: #ifdef TESTDLL_EXPOR...
  • 动态链接库理解(一)

    2015-01-25 20:26:44
    那么我们怎么查看一个dll中有哪些函数是被导出的呢? 我们Visual Studio中的一个工具查看,具体步骤是: 1、进入dos 2、今天dll所在的路径 3、使用dumpbin命令(如果在dos下找不到dumpbin,我们可以进入Visual的...
  • VC++6.0写了一个简单的dll,然后我电脑上还装有VS2013(在此之前还装过VS2012,已卸载,不知有没有卸载干净)。然后我想VS/vc/bin/下的dumpbin.exe来查看,我的vs是放在e盘。然后打开后是下面的图一样,输入...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 136
精华内容 54
关键字:

dll动态链接库怎么用