C 调用外部dll
LabwindowsCVI调用外部DLL文件的问题

}
}
这样的目的是:在外部调用的时候,便于调用。
C源文件编写完整后,把相关的*.uir文件添加到工程中,然后编写一个*.h文件,命名为exampledll.h,里面包含一个源文件中的函数申明。定义如下:
externint InitUIForDLL (void);//调用面板的函数
InitUIForDLL ();
return 0;
}
(2)通过一个按键来调用dll,即在一个工程中通过一个按钮来调取dll中的函数,来完成此按扭的功能。
与用c源代码来调用的方式一样,只是此工程已经有*.uir对象面板,在*.uir的面板上添加一个按钮,为按钮生成一个函数,在函数中调用外部dll中的函数。在编译前,要将*.lib和*.dll文件和头文件包含在工程中,并且将dll中的函数用一个*.h头文件包含:
int __stdcall DllEntryPoint (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
这两个函数是DLL动态链接库必须包含的两个函数,函数的具体内容为:
#include <cvirte.h>
int __stdcall DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
#include "CFI.h"
static int panelHandle;
int main (int argc, char *argv[])
{
if (InitCVIRTE (0, argv, 0) == 0)
return -1;/* out of memory */
C#调用第三方DLL完整实例

C#调⽤第三⽅DLL完整实例分类: C/C++以下代码为本⼈在实际项⽬中编写的调⽤第三⽅DLL接⼝程序的完整代码。
public class ExecuteDLL : Form{...//忽略与调⽤DLL⽆关的代码private IntPtr hModule = IntPtr.Zero;/// <summary>/// 调⽤HIS系统提供的DLL接⼝程序查看检查申请单///DLL的名称:H62AppQueryToPacs.dll///函数名说明:///function THandle HLoginProc(THandlea AppHandle, THandle aCallWinHandle,THandle aPluginHandle /// PChar aBqno,PChar aEmpno,PChar aPatno);///传⼊变量参数说明:///// aAppHandle: THandle; //应⽤程序句柄///// aCallWinHandle: THandle; //调⽤窗⼝句柄///// aPluginHandle: THandle; // 插件的句柄///// aEmpno,PChar;//医⽣⼯号///// aBqno: PChar;//病区代码///// aPatno: PChar;//病⼈记账号/// </summary>/// <param name="lpFileName"></param>/// <returns></returns>//申明外部API[DllImport("kernel32.dll")]static extern IntPtr LoadLibrary(string lpFileName);[DllImport("kernel32.dll")]static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);[DllImport("kernel32", EntryPoint = "FreeLibrary", SetLastError = true)]static extern bool FreeLibrary(IntPtr hModule);//申明委托private delegate IntPtr HLoginProc(IntPtr aAppHandle, IntPtr aCallWinHandle, IntPtr aPluginHandle,string aBqno, string aEmpno, string aPatno);//获取函数地址private Delegate GetFunctionAddress(IntPtr dllModule, string functionName, Type t){IntPtr address = GetProcAddress(dllModule, functionName);if (address == IntPtr.Zero)return null;elsereturn Marshal.GetDelegateForFunctionPointer(address, t);}//按钮单击事件private void button_CheckList_Click(object sender, EventArgs e){try{SIS_Model.MWorkList smWorkList;PACS_Model.MWorkList pmWorkList;string strNo = "";switch (GetConfig.DALAndModel){case "SIS":smWorkList = (SIS_Model.MWorkList)this.iWorkList;strNo = (smWorkList.INPATIENTNO == null ? "" : smWorkList.INPATIENTNO.ToString());// 病⼈记账号 "875624"; break;case "PACS":pmWorkList = (PACS_Model.MWorkList)this.iWorkList;strNo = (pmWorkList.INPATIENTNO == null ? "" : pmWorkList.INPATIENTNO.ToString());// 病⼈记账号 "875624"; break;}if (strNo.Trim() == ""){MessageBox.Show("⽆法获取患者ID,请确认操作步骤是否正确");return;}//加载DLLtry{string strDLLPath = Environment.CurrentDirectory + "\\HuiTong\\JianChaShenQingDan\\H62AppQueryToPacs.dll"; hModule = LoadLibrary(strDLLPath);if (hModule.Equals(IntPtr.Zero)){MessageBox.Show("导⼊DLL失败");return;}}catch (Exception ex){MessageBox.Show(ex.Message.ToString());FreeLibrary(hModule);hModule = IntPtr.Zero;return;}//将要调⽤的⽅法转换为委托:hModule为DLL的句柄,"HLoginProc"为DLL中⽅法的名称HLoginProc farProc = (HLoginProc)this.GetFunctionAddress(hModule, "HLoginProc", typeof(HLoginProc)); if (farProc == null){FreeLibrary(hModule);hModule = IntPtr.Zero;return;}//利⽤委托执⾏DLL⽂件中的接⼝⽅法farProc(hModule, IntPtr.Zero, IntPtr.Zero, null, null, strNo);FreeLibrary(hModule);hModule = IntPtr.Zero;}catch (Exception ex){MessageBox.Show(ex.Message.ToString());FreeLibrary(hModule);hModule = IntPtr.Zero;return;}}}版权申明:此⽂为作者原创,转载请提供原始⽂章链接,谢谢!。
总结的c#调用DLL方法

小结:
动态链接具有下列优点:
节省内存和减少交换操作。很多进程可以同时使用一个DLL,在内存中共享该DLL的一个副本。相反,对于每个用静态链接库生成的应用程序,Windows必须在内存中加载库代码的一个副本。
节省磁盘空间。许多应用程序可在磁盘上共享DLL的一个副本。相反,每个用静态链接库生成的应用程序均具有作为单独的副本链接到其可执行图像中的库代码。
long maxcd = MaxCDClass.MaxCD(num1,num2);
Console.WriteLine("The MaxCD of {0} and {1} is {2}",num1, num2, maxcd);
}
}
若要生成可执行文件MyClient.exe,请使用以下命令行:
csc /out:MyClient.exe /reference:MyLibrary.DLL MyClient.cs
升级到DLL更为容易。DLL中的函数更改时,只要函数的参数和返回值没有更改,就不需重新编译或重新链接使用它们的应用程序。相反,静态链接的对象代码要求在函数更改时重新链接应用程序。
提供售后支持。例如,可修改显示器驱动程序DLL以支持当初交付应用程序时不可用的显示器。
支持多语言程序。只要程序遵循函数的调用约定,用不同编程语言编写的程序就可以调用相同的DLL函数。程序与DLL函数在下列方面必须是兼容的:函数期望其参数被推送到堆栈上的顺序,是函数还是应用程序负责清理堆栈,以及寄存器中是否传递了任何参数。
}
(3)在CS编辑器中再次添加一个CS文件,名字自取,但包函main入口函数,在这个文件中便可以引用C++写的DLL文件中的函数了
c++中生成动态库,外工程调用动态库的配置方法

C++中,由工程生成、调用dll的方法一、由工程生成dllSetp1:右键点开工程属性-常规,将配置类型中exe改为dll动态库,随后点击确认。
图1 将exe类型改为dllStep2:右键点开工程属性-c++/c中的预处理器,点开预处理器中的定义,点击编辑,在编辑框中加入:工程名_EXPORTS(大写)图2 在预处理器中定义,加入工程名_EXPORTSStep3:在工程下的头文件筛选器中,新建全局头文件,头文件格式如下:图3在项目中新建全局头文件Step4:把第三步生成的头文件,#include到同工程中的每一个头文件中,即该工程中的每一个头文件均引用全局头文件图4 把第三步新建的头文件引入项目的其余头文件中Step5:在各头文件中,在类的标识符后面,类名的前面;或者函数名的前面加入ccc_API(工程名称_API)图5 在各头文件的类声明中加入工程名称_API Setp6:右键工程属性,点击c++/c常规中的附加包含目录,选择头文件所在目录,点击确认。
图6 附加包含目录Step7:右键工程清理,随后点击生成,当命令栏显示成功生成时,表示成功生成该工程的dll和lib文件图7 点击生成产生dll和lib文件%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 可在工程文件的Debug文件夹中找到dll和lib文件,在工程文件名,同文件名下的文件夹中找到头文件,若外部程序需要调用此工程,仅需将以上文件导出即可。
图8 外部调用程序二、由外部工程调用dllStep1:右键调用dll文件的工程属性,点击链接器-常规-附加库目录,添加包含动态链接库涉及的头文件和lib文件的文件夹。
图9 调入文件的文件夹设定Step2:右键工程属性,点击链接器-输入-附加依赖项,点击编辑,添加调入动态库的Lib文件名称,格式为工程名,lib(和生成库的名称一致)图10 附加依赖项配置Step3:将导入的dll文件,放在应用工程的.EXE文件所在文件夹中,即解决方案的Debug(release)中。
C#调用DLL的详细步骤

中国传媒大学 计算;b; } DLL 需传出 char *类型 [DllImport(“MyDLL.dll")] // 传出值 public static extern int mySum (StringBuilder abuf, StringBuilder bbuf );//DLL 中申明 extern “C” __declspec(dllexport) int WINAPI mySum(char * astr,char * bstr) { //传出 char * 改变 astr bstr -->abuf, bbuf 可以被改变 return a+b; } (3)传递结构参数 DLL 传递结构(见代码) BOOL PtInRect(const RECT *lprc, POINT pt); using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential)] public struct Point { public int x; public int y; } [StructLayout(LayoutKind.Explicit)] public struct Rect { [FieldOffset(0)] public int left; [FieldOffset(4)] public int top; [FieldOffset(8)] public int right; [FieldOffset(12)] public int bottom; } Class XXXX { [DllImport("User32.dll")] public static extern bool PtInRect(ref Rect r, Point p); } 在此原型中,我们用“ref”指明将传递结构指针而不是结构值。这是处理通过指针传递的 结构的一般方法。
调用外部Dll

调用外部Dll调用外部Dll的点点滴滴调用外部DLL的方法有两种:1. (单个脚本中)在脚本中是使用 lr_load_dll 函数。
2. (全局设置,所有脚本)通过修改 mdrv.dat 文件实现。
对DLL的要求 VuGen只能识别标准C编译的DLL,所以使用VC6创建的函数必须在函数开头加上extern "C",它告诉编译器对这个函数按照标准C的方式进行编译。
而如果你想调用C#编译出来DLL,那就只能望而却步啦。
如何想查看DLL中是否有符合要求的导出函数,可以使用微软的SDK里自带的Dependency Walker工具。
DLL的创建启动VC6,新建一个Win32 Dynamic-Link Library 的工程,取名:LRDllTest在这里,我们创建一个简单的求和函数Sum,并什么为导出函数,关键代码如下:#define LRDLLTEST_API __declspec(dllexport)extern"C" LRDLLTEST_API int Sum(int a , int b);//a + bLRDLLTEST_API int Sum(int a , int b){return a + b;}编译,生成DLL:LRDllTest.dlllr_load_dll方法有了符合要求的DLL,调用lr_load_dll函数显得非常的简单。
lr_load_dll的函数原型是:lr_load_dll(library_name); 所以,只需要调用该函数,传入需要引用的DLL路径,如果DLL放在脚本目录里,可直接写相对路径。
这里,我推荐把该函数放在vuser_init这个Action里,一方面是由于vuser_init只会执行一次,如果我们放在中间的那个默认的Action中的话,DLL可能会被装载多次,这是没有必要的。
另一方面,装载DLL也需要一定的性能开销,所以作为初始环境设置将它放在vuser_init中更加合理。
如何用VC创建及调用DLL

如何用VC创建及调用DLL使用Visual C++(VC++)创建和调用动态链接库(DLL)可以提供一种模块化的方式来组织和重用代码。
本文将介绍如何使用VC++创建DLL,并在另一个VC++项目中调用该DLL。
创建DLL以下是使用VC++创建DLL的步骤:1.打开VC++,在“文件”菜单中选择“新建”->“项目”。
2. 在“新建项目”对话框中,选择“Win32控制台应用程序”。
点击“下一步”。
3.输入项目名称,并选择项目位置,点击“下一步”。
4.在“应用程序类型”对话框中,选择“DLL”并取消勾选“预编译头”。
点击“下一步”。
5.在“进入代码”对话框中,选择“空项目”。
点击“完成”。
6. 创建一个新的源文件,例如“MyDLL.cpp”。
7. 在“MyDLL.cpp”中,编写所需的函数并导出。
例如:```C++#include <Windows.h>// 导出的函数需要使用__declspec(dllexport)修饰extern "C" __declspec(dllexport) int AddNumbers(int a, int b) return a + b;```8. 在项目属性中,选择“链接器”->“高级”,将“入口点”设置为“DllMain”。
9.在“生成”菜单中选择“生成解决方案”,以生成DLL文件。
以下是在VC++项目中调用DLL的步骤:1.打开VC++,在“文件”菜单中选择“新建”->“项目”。
2. 在“新建项目”对话框中,选择“Win32控制台应用程序”。
点击“下一步”。
3.输入项目名称,并选择项目位置,点击“下一步”。
4.在“应用程序类型”对话框中,选择“控制台应用程序”并取消勾选“预编译头”。
点击“下一步”。
5.在“附加选项”对话框中,勾选“空项目”。
点击“完成”。
6.将之前生成的DLL文件复制到新项目的文件夹中。
7.在项目属性中,选择“C/C++”->“常规”,将“附加包含目录”设置为包含DLL文件的文件夹路径。
C# 调用外部dll

C# 调用外部dll一、DLL与应用程序动态链接库(也称为DLL,即为“Dynamic Link Library”的缩写)是Microsoft Windows 最重要的组成要素之一,打开Windows系统文件夹,你会发现文件夹中有很多DLL文件,Windows 就是将一些主要的系统功能以DLL模块的形式实现。
动态链接库是不能直接执行的,也不能接收消息,它只是一个独立的文件,其中包含能被程序或其它DLL调用来完成一定操作的函数(方法。
注:C#中一般称为“方法”),但这些函数不是执行程序本身的一部分,而是根据进程的需要按需载入,此时才能发挥作用。
DLL只有在应用程序需要时才被系统加载到进程的虚拟空间中,成为调用进程的一部分,此时该DLL也只能被该进程的线程访问,它的句柄可以被调用进程所使用,而调用进程的句柄也可以被该DLL所使用。
在内存中,一个DLL只有一个实例,且它的编制与具体的编程语言和编译器都没有关系,所以可以通过DLL来实现混合语言编程。
DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。
下面列出了当程序使用 DLL 时提供的一些优点:[1]1)使用较少的资源当多个程序使用同一个函数库时,DLL 可以减少在磁盘和物理内存中加载的代码的重复量。
这不仅可以大大影响在前台运行的程序,而且可以大大影响其他在 Windows 操作系统上运行的程序。
2)推广模块式体系结构DLL 有助于促进模块式程序的开发。
这可以帮助您开发要求提供多个语言版本的大型程序或要求具有模块式体系结构的程序。
模块式程序的一个示例是具有多个可以在运行时动态加载的模块的计帐程序。
3)简化部署和安装当 DLL 中的函数需要更新或修复时,部署和安装 DLL 不要求重新建立程序与该 DLL 的链接。
此外,如果多个程序使用同一个 DLL,那么多个程序都将从该更新或修复中获益。
当您使用定期更新或修复的第三方 DLL 时,此问题可能会更频繁地出现。
C#工程调用外部的DLL文件

C#工程调用外部的DLL文件在.NET编程中,我们会经常碰到要调用外部的DLL文件。
首先,动态链接库文件(DLL)的格式其实和EXE文件相同,都是可执行的,不同的是EXE可单独运行,而DLL往往是供其他程序动态的调用,它不主动的执行任何代码。
其次,链接库可分为两种:静态链接库和动态链接库。
静态链接库是在程序编译的时候静态的链接到程序中去的,这样编译完后文件体积变大了。
动态链接库是程序在运行的时候动态的把DLL中的函数链接到程序中执行,这样就不用在编译的时候链接文件了,因此节省了文件大小。
在.NET平台下C#如何调用DLL文件呢?首先我们构造一个自己的DLL文件。
假设,我们已经有一个.h文件和.lib文件。
.h文件:int add(int x,int y);int minux(int x,int y);构造DLL文件:1.新建一个VC++ Class Library工程2.添加2个头文件math.h,imath.h和cpp文件imath.cppmath.h:int add(int x,int y);int minus(int x,int y);imath.h:extern "C"{__declspec(dllexport) int Add(int x,int y);__declspec(dllexport) int Minus(int x,int y);}imath.cpp:int Add(int x,int y){return add(x,y);}int Minus(int x,int y){return minus(x,y);}编译生成DLL文件imath.dll3.在C#工程中调用imath.dll中的Add,MinusC#调用外部DLL文件,需要使用using System.Runtime.InteropServices;导入命名空间接着定义要调用到的函数:[DllImport("imath.dll",EntryPoint="Add")]private static extern int Add(int x,int y);[DllImport("imath.dll",EntryPoint="Minus")]private static extern int Minus(int x,int y);至此以后就可以在需要调用Add和Minus的地方直接调用Add 和Minus了。
C#调用C++的dll两种方法(托管与非托管)

C#调⽤C++的dll两种⽅法(托管与⾮托管)C#与C++交互,总体来说可以有两种⽅法:利⽤PInvoke实现直接调⽤⾮托管C++利⽤C++/CLI作为代理中间层⼀、⾮托管C++由于C#编写的是托管代码,编译⽣成微软中间语⾔,⽽C++代码则编译⽣成本地机器码(这种C++也有叫做本地C++或者⾮托管C++,VC6.0就是⽤于开发⾮托管C++代码的平台),这两种语⾔进⾏混合编程就存在⼀定困难。
⽐较常⽤的⽅法是使⽤DllImport的⽅法,这种⽅法在⽹上有很多介绍,这⾥就不详细叙述了。
但是⽤过这种⽅法的⼈都知道这种⽅法对于导出函数还可以但是却没法导出⾮托管C++类!⾮常的要命。
extern "C"外部声明,表⽰函数和变量是按照C语⾔的⽅式编译和链接的。
__decspec(dllexport)的⽬的是为了将对应的函数放⼊到DLL动态库中。
extern "C" _declspec(dllexport)的⽬的是为了使⽤DllImport调⽤⾮托管C++的DLL⽂件。
因为使⽤DllImport只能调⽤由C语⾔函数做的DLL。
⼆、托管C++ 与 C++/CLI除了C#、⾮托管C++外,C系列中还存在⼀种语⾔叫做托管C++,这种语⾔语法上和⾮托管C++⼏乎⼀样,但是却和C#⼀样编译成为微软中间语⾔,这样托管C++就可以和C#良好地通信,即可以在C#中使⽤托管C++类。
另外,托管C++还有两个及其重要的特性就是:可以调⽤⾮托管C++的类和函数!托管C++的程序集可以嵌套⾮托管C++编译的机器码!所以我们的技术路径也就明晰了:C#以托管C++为中介调⽤⾮托管C++的类和函数。
换句话说也就是⽤托管C++给⾮托管C++代码做⼀个外壳包装供C#调⽤。
托管C++托管C++已经被废弃,C++托管代码的现代扩展叫做C++/CLIC++/CLIC++/CLI 是微软推出的⼀个跑在 CLI 上的语⾔,它的主要特性都包含在名字⾥了:1. 语法基于 C++,理论上讲是 C++ 语⾔的超集,⾯向 CLI 部分的语法是微软⾃创的⼀套新语法。
C#反射调用外部Dll,执行其中异步函数并取返回值

C#反射调⽤外部Dll,执⾏其中异步函数并取返回值using System.Reflection;1.载⼊DllAssembly asm=Assembly.LoadFile(FullPath);//FullPath 为Dll所在位置的全路径。
2.取得所需要的类的类型Type t = asm.GetType("namespaceName.className");//命名空间名.类名3.建⽴此类型的对象(相当于 new)object o = Activator.CreateInstance(t); //创建Type t类型的对象4.取得类中想要执⾏的⽅法MethodInfo me = t.GetMethod("TestFunction");5.取得此⽅法所需参数列表ParameterInfo[] para=me.GetParameters();6.创建参数类型的对象,并传⼊参数ArrayType re = asm.GetType("TestDll.ReturnClass"); //我的参数类型是TestDll命名空间下 ReturnClass类object reo = Activator.CreateInstance(re);object[] r = { reo };7.调⽤函数Object rr = me.Invoke(o, r); //如果调⽤的是⾮异步函数,此时object rr就是函数的返回值。
8.如果调⽤的是异步函数Task task = me.Invoke(o, r) as Task;await task;object result = task.GetType().GetProperty("Result").GetValue(task, null); //result就是异步函数的返回值9.反射常⽤操作//取得o实例中propertyName属性的值valueType t = asm.GetType("TestDll.TestClass");object o = Activator.CreateInstance(t);object getproperty = t.GetProperty("propertyName").GetValue(o, null); //⽅法⼀object getproperty1 = o.GetType().GetProperty("propertyName").GetValue(o, null); //⽅法⼆//取得枚举类型中的指定元素Type enumType = asm.GetType("namespaceName.enumName");foreach(var name in Enum.GetValues(enumType)){if("elementname"==name.ToString()){Convert.ToInt32(name);//转化制定元素为int}}string[] strname=Enum.GetNames(enumType);//取得枚举所有元素名10.总结⼤概就是,在你不知道Dll的内部结构的情况下,可以通过反射获得Dll内所有信息。
VC如何调用DLL文件

也可以采用动态加载的方式调用,步骤如下:Another.dll有一个int Add(int x,int y) 函数。
则完整的调用过程如下:typedef int (* DllCallFunCtion)(int,int); //定义函数指针DllCallFunCtion funPtr;Handle handle =LoadLibrary("Another.dll");funPtr =(DllCallFunCtion)GetProcAddress(handle ,"Add");funPtr(2,3); // 2+3;FreeLibrary(handle); // 释放载入的动态库调用DLL,首先需要将DLL文件映像到用户进程的地址空间中,然后才能进行函数调用,这个函数和进程内部一般函数的调用方法相同。
Windows提供了两种将DLL映像到进程地址空间的方法:1. 隐式的加载时链接这种方法需要DLL工程经编译产生的LIB文件,此文件中包含了DLL允许应用程序调用的所有函数的列表,当链接器发现应用程序调用了LIB文件列出的某个函数,就会在应用程序的可执行文件的文件映像中加入一些信息,这些信息指出了包含这个函数的DLL文件的名字。
当这个应用程序运行时,也就是它的可执行文件被操作系统产生映像文件时,系统会查看这个映像文件中关于DLL的信息,然后将这个DLL文件映像到进程的地址空间。
系统通过DLL文件的名称,试图加载这个文件到进程地址空间时,它寻找DLL 文件的路径按照先后顺序如下:·程序运行时的目录,即可执行文件所在的目录;·当前程序工作目录·系统目录:对于Windows95/98来说,可以调用GetSystemDirectory函数来得到,对于WindowsNT/2000来说,指的是32位Windows的系统目录,也可以调用GetSystemDirectory函数来得到,得到的值为SYSTEM32。
C#调用其他语言编写的dll方法

InitializeComponent(); } privatevoidbutton1_Click(objectsender,EventArgse) {
textBox3.Text=cCdll.Sum(Convert.ToDouble(textBox1.Text),Convert.ToDouble(textBox2.Te xt)).ToString();
下面的示例说明如何使用 DllImport 属性调用非托管的 DLL。
[DllImport("KERNEL32.DLL",EntryPoint="MoveFileW", SetLastError=true, CharSet=CharSet.Unicode,ExactSpelling=true, CallingConvention=CallingConvention.StdCall)] publicstaticexternboolMoveFile(Stringsrc,Stringdst);
在程序开发过程,有时会遇到使用 C#调用其他编程语言开发的 DLL 或调用 Windows 系统 API 函数,由于这些 DLL 都属于非托管动态链接库 (DLL),那么要调用非托管动态链接库 (DLL)需要使用 DllImport 属性。
DllImport 属性指示该属性化方法由非托管动态链接库(DLL)作为静态入口点公开,并提 供对从非托管 DLL 导出的函数进行调用所必需的信息。作为最低要求,必须提供包含入口 点的 DLL 的名称。在使用 DllImport 属性前,须引用命名空间: System.Runtime.InteropServ要调用的 DLL 入口点的名称或序号
C语言的DLL编写与调用

C语言的DLL编写
1、打开C语言的Microsoft Visual C++ 6.0
2、选择file--> new ,在project选项中选择MFC AppWizard(dll),给工程起名字,选择保存
路径。
3、选择Regular DLL using shared MFC DLL,点击finish
4、此时工程的结构图如下所示
5、在FourthSample源文件中写上对外暴露的dll函数方法
6、在FourthSample.def中追加对外暴露的方法名
7、选中FourthSample.cpp,编译源文件
8、生成dll文件
9、注意事项:在编译源文件时可能要报以下错误,
解决方法:
选中该源文件,点击右键Settings,
再次编译,通过。
C语言调用DLL
1、新建一个c的源文件,进行dll调用的测试
2、源代码如下,代码中有关键词用法,请参考其他资料
3、弹出一个对话框,说明dll调用成功。
注意事项:注意将test.dll动态链接库放在该程序目录下(FourthSample.dll重名为test.dll)。
VS2024环境下实现C程序调用由C源代码编译得到的DLL文件

VS2024环境下实现C程序调用由C源代码编译得到的DLL文件在VS2024环境下,实现C程序调用由C源代码编译得到的DLL文件可以按以下步骤进行:1. 创建工程:首先在Visual Studio 2024中创建一个新的工程,选择C/C++ -> Win32控制台应用程序,然后为项目指定一个名称和位置,点击“下一步”。
2.配置项目属性:在项目属性中,选择“常规”选项卡,将“字符集”设置为“使用多字节字符集”。
3. 设置 DLL 选项:在项目属性中,选择“配置属性” -> “常规” -> “目标文件扩展名”,将其更改为“.dll”。
然后选择“配置类型”为“动态库(.dll)”。
4.添加C源代码文件:在项目中添加C源代码文件,可以在源文件夹中右键单击,选择“添加”->“现有项”,选择C源代码文件并点击“添加”。
5. 编译DLL文件:使用VS2024编译生成DLL文件。
在生成之前,确保C源代码文件中的函数被导出,可以使用`__declspec(dllexport)`关键字进行导出。
例如,在要导出的函数声明前添加`__declspec(dllexport)`关键字:`__declspec(dllexport) int MyFunction(int param);`。
6. 编写调用DLL的C程序:在项目中添加一个新的C源代码文件,用于调用DLL文件中导出的函数。
在该源代码文件中,使用`#include`指令引入DLL的头文件,并使用动态链接库的方式,即使用`LoadLibrary`函数加载DLL文件,通过`GetProcAddress`函数获取DLL函数的地址,然后可以调用该函数。
例如:```c#include <stdio.h>#include <Windows.h>HMODULE hModule = LoadLibrary("YourDll.dll");if (hModule != NULL)//获取DLL函数地址FARPROC fnAddress = GetProcAddress(hModule, "YourFunction");if (fnAddress != NULL)//调用DLL函数int result = ((int(*)()fnAddress)(;//输出结果printf("Result: %d\n", result);}FreeLibrary(hModule);```7.构建和运行程序:编译和构建整个项目,然后运行生成的可执行文件,即可看到调用DLL函数的结果。
(精品word)--C# 调用外部dll

(精品word)--C# 调用外部dllC# 调用外部dll一、DLL与应用程序动态链接库(也称为DLL,即为“Dynamic Link Library”的缩写)是Microsoft Windows最重要的组成要素之一,打开Windows系统文件夹,你会发觉文件夹中有很多DLL文件,Windows就是将一些主要的系统功能以DLL模块的形式实现。
动态链接库是不能挺直执行的,也不能接收消息,它只是一个独立的文件,其中包含能被程序或其它DLL调用来完成确定操作的函数(方法。
注:C#中一般称为“方法”),但这些函数不是执行程序本身的一部分,而是依据进程的需要按需载入,此时才能发挥作用。
DLL只有在应用程序需要时才被系统加载到进程的虚拟空间中,成为调用进程的一部分,此时该DLL也只能被该进程的线程访问,它的句柄可以被调用进程所用法,而调用进程的句柄也可以被该DLL 所用法。
在内存中,一个DLL只有一个实例,且它的编制与具体的编程语言和编译器都没有关系,所以可以通过DLL来实现混合语言编程。
DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程全部。
下面列出了当程序用法DLL 时供应的一些优点:[1]1)用法较少的资源当多个程序用法同一个函数库时,DLL 可以削减在磁盘和物理内存中加载的代码的重复量。
这不仅可以大大影响在前台运行的程序,而且可以大大影响其他在Windows 操作系统上运行的程序。
2)推广模块式体系结构DLL 有助于促进模块式程序的开发。
这可以忧虑您开发要求供应多个语言版本的大型程序或要求具有模块式体系结构的程序。
模块式程序的一个示例是具有多个可以在运行时动态加载的模块的计帐程序。
3)简化部署和安装当DLL 中的函数需要更新或修复时,部署和安装DLL 不要求重新建立程序与该DLL 的链接。
此外,假如多个程序用法同一个DLL,那么多个程序都将从该更新或修复中获益。
当您用法定期更新或修复的第三方DLL 时,此问题可能会更频繁地消灭。
C# 调用外部dll

C# 调用外部dll一、DLL与应用程序动态链接库(也称为DLL,即为“Dynamic Link Library”的缩写)是Microsoft Windows 最重要的组成要素之一,打开Windows系统文件夹,你会发现文件夹中有很多DLL文件,Windows就是将一些主要的系统功能以DLL模块的形式实现。
动态链接库是不能直接执行的,也不能接收消息,它只是一个独立的文件,其中包含能被程序或其它DLL调用来完成一定操作的函数(方法。
注:C#中一般称为“方法”),但这些函数不是执行程序本身的一部分,而是根据进程的需要按需载入,此时才能发挥作用。
DLL只有在应用程序需要时才被系统加载到进程的虚拟空间中,成为调用进程的一部分,此时该DLL也只能被该进程的线程访问,它的句柄可以被调用进程所使用,而调用进程的句柄也可以被该DLL所使用。
在内存中,一个DLL只有一个实例,且它的编制与具体的编程语言和编译器都没有关系,所以可以通过DLL来实现混合语言编程。
DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。
下面列出了当程序使用DLL 时提供的一些优点:[1]1)使用较少的资源当多个程序使用同一个函数库时,DLL 可以减少在磁盘和物理内存中加载的代码的重复量。
这不仅可以大大影响在前台运行的程序,而且可以大大影响其他在Windows 操作系统上运行的程序。
2)推广模块式体系结构DLL 有助于促进模块式程序的开发。
这可以帮助您开发要求提供多个语言版本的大型程序或要求具有模块式体系结构的程序。
模块式程序的一个示例是具有多个可以在运行时动态加载的模块的计帐程序。
3)简化部署和安装当DLL 中的函数需要更新或修复时,部署和安装DLL 不要求重新建立程序与该DLL 的链接。
此外,如果多个程序使用同一个DLL,那么多个程序都将从该更新或修复中获益。
当您使用定期更新或修复的第三方DLL 时,此问题可能会更频繁地出现。
VC如何调用DLL文件

一、LIB文件目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)。
静态库是一个或者多个obj文件的打包,所以有人干脆把从obj文件生成lib的过程称为Archive,即合并到一起。
比如你链接一个静态库,如果其中有错,它会准确的找到是哪个obj有错,即静态lib只是壳子。
动态库一般会有对应的导入库,方便程序静态载入动态链接库,否则你可能就需要自己LoadLibary调入DLL文件,然后再手工GetProcAddress获得对应函数了。
有了导入库,你只需要链接导入库后按照头文件函数接口的声明调用函数就可以了。
导入库和静态库的区别很大,他们实质是不一样的东西。
静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。
这也是实际上很多开源代码发布的惯用方式:预编译的开发包:包含一些.dll文件和一些.lib文件。
其中这里的.lib就是导入库,而不要错以为是静态库。
但是引入方式和静态库一样,要在链接路径上添加找到这些.lib的路径。
而.dll则最好放到最后产生的应用程序exe执行文件相同的目录。
这样运行时,就会自动调入动态链接库。
用户自己编译:下载的是源代码,按照readme自己编译。
生成很可能也是.dll + .lib(导入库)的库文件知道DLL函数原型:并且你知道dll中函数的函数原型,那么你可以直接在自己程序中使用LoadLibary调入DLL 文件,GetProcAddress获取函数地址,然后调用。
二、静态链接库与动态链接库区别静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的EXE 文件中了。
C#调用CC++DLL方式

C#调用CC++DLL方式1、编写一个简单的DLL设置为导出函数,并采用C风格。
函数前加extern "C" __declspec(dllexport)。
定义函数在退出前自己清空堆栈,在函数前加__stdcall。
新建一个头文件,在头文件中:/* 加入任意你想加入的函数定义*/extern "C" _declspec(dllexport) int _stdcall add(int *x,int *y); // 声明为C编译、链接方式的外部函数extern "C" _declspec(dllexport) int _stdcall sub(int x,int y); // 声明为C编译、链接方式的外部函数新建一个.cpp文件#include "mydll.h"//貌似这两个头文件的顺序不能颠倒。
我试了很多次,但是不能确定。
int add(int *x,int *y)//是否可以理解为,VS2010已经默认是_stdcall,所以函数不用添加该修饰符{return *x+*y;}int sub(int x,int y){return x-y;}把导出函数名称变为标准名称,需加模块定义文件,就是.def文件。
内容如下:(需要注释,前面加分号就可以了,注释需要单独行)LIBRARY "TEST"EXPORTS;add函数add;sub函数subLIBRARY 库名称EXPORTS 需要导出的各个函数名称重新编译之后,再用Depends工具看一下,函数已经变成标准add。
这个在动态加载时很有用,特别是在GetProcAddress函数寻找入库函数的时候。
2、静态调用新建一个C#的控制台项目,using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Runtime.InteropServices;//添加namespace mytest{class Program{//----------------------------------------------------------------------------------------------[DllImport("mydll.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]extern static int add(ref int a, ref int b);[DllImport("mydll.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]extern static int sub(int a, int b);//--------------------------------------------------------------------------------------------------static void Main(string[] args){int a, b,c,d;a = 1;b = 2;c=d= 0;Console.WriteLine(add(ref a,ref b).ToString());Console.WriteLine(sub(b,a).T oString());Console.Read();}}}3、动态调用using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Runtime.InteropServices;//添加namespace mytest{class Program{[DllImport("kernel32.dll")]private extern static IntPtr LoadLibrary(String path);//path 就是dll路径返回结果为0表示失败。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C# 调用外部dll一、DLL与应用程序动态链接库(也称为DLL,即为“Dynamic Link Library”的缩写)是Microsoft Windows 最重要的组成要素之一,打开Windows系统文件夹,你会发现文件夹中有很多DLL文件,Windows就是将一些主要的系统功能以DLL模块的形式实现。
动态链接库是不能直接执行的,也不能接收消息,它只是一个独立的文件,其中包含能被程序或其它DLL调用来完成一定操作的函数(方法。
注:C#中一般称为“方法”),但这些函数不是执行程序本身的一部分,而是根据进程的需要按需载入,此时才能发挥作用。
DLL只有在应用程序需要时才被系统加载到进程的虚拟空间中,成为调用进程的一部分,此时该DLL也只能被该进程的线程访问,它的句柄可以被调用进程所使用,而调用进程的句柄也可以被该DLL所使用。
在内存中,一个DLL只有一个实例,且它的编制与具体的编程语言和编译器都没有关系,所以可以通过DLL来实现混合语言编程。
DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。
下面列出了当程序使用DLL 时提供的一些优点:[1]1)使用较少的资源当多个程序使用同一个函数库时,DLL 可以减少在磁盘和物理内存中加载的代码的重复量。
这不仅可以大大影响在前台运行的程序,而且可以大大影响其他在Windows 操作系统上运行的程序。
2)推广模块式体系结构DLL 有助于促进模块式程序的开发。
这可以帮助您开发要求提供多个语言版本的大型程序或要求具有模块式体系结构的程序。
模块式程序的一个示例是具有多个可以在运行时动态加载的模块的计帐程序。
3)简化部署和安装当DLL 中的函数需要更新或修复时,部署和安装DLL 不要求重新建立程序与该DLL 的链接。
此外,如果多个程序使用同一个DLL,那么多个程序都将从该更新或修复中获益。
当您使用定期更新或修复的第三方DLL 时,此问题可能会更频繁地出现。
二、DLL的调用每种编程语言调用DLL的方法都不尽相同,在此只对用C#调用DLL的方法进行介绍。
首先,您需要了解什么是托管,什么是非托管。
一般可以认为:非托管代码主要是基于win 32平台开发的DLL,activeX的组件,托管代码是基于.net平台开发的。
如果您想深入了解托管与非托管的关系与区别,及它们的运行机制,请您自行查找资料,本文件在此不作讨论。
(一)调用DLL中的非托管函数一般方法首先,应该在C#语言源程序中声明外部方法,其基本形式是:[DLLImport(“DLL文件”)]修饰符extern 返回变量类型方法名称(参数列表)其中:DLL文件:包含定义外部方法的库文件。
修饰符:访问修饰符,除了abstract以外在声明方法时可以使用的修饰符。
返回变量类型:在DLL文件中你需调用方法的返回变量类型。
方法名称:在DLL文件中你需调用方法的名称。
(二)动态装载、调用DLL中的非托管函数在上面已经说明了如何用DllImport调用DLL中的非托管函数,但是这个是全局的函数,假若DLL中的非托管函数有一个静态变量S,每次调用这个函数的时候,静态变量S就自动加1。
结果,当需要重新计数时,就不能得出想要的结果。
下面将用例子说明:1.DLL的创建1)启动Visual C++ 6.0;2)新建一个“Win32 D ynamic-Link Library”工程,工程名称为“Count”;3)在“Dll kind”选择界面中选择“A simple dll project”;4)打开Count.cpp,添加如下代码:// 导出函数,使用“ _stdcall ” 标准调用extern "C" _declspec(dllexport)int _stdcall count(int init);int _stdcall count(int init){//count 函数,使用参数init 初始化静态的整形变量S ,并使S 自加1后返回该值static int S=init;S++;return S;}5)按“F7”进行编译,得到Count.dll(在工程目录下的Debug文件夹中)。
2.用DllImport调用DLL中的count函数1)打开项目“Tzb”,向“Form1”窗体中添加一个按钮。
2)改变按钮的属性:Name为“B2”,Text为“用DllImport调用DLL中count函数”,并将按钮B1调整到适当大小,移到适当位置。
3)打开“Form1.cs”代码视图,使用关键字static 和extern 声明方法“count”,并使其具有来自Count.dll 的导出函数count的实现,代码如下:[DllImport("Count.dll")]static extern int count(int init);4)在“Form1.cs[设计]”视图中双击按钮B2,在“B2_Click”方法体内添加如下代码:MessageBox.Show(" 用DllImport 调用DLL 中的count 函数,\n传入的实参为0 ,得到的结果是:"+count(0).ToString()," 挑战杯");MessageBox.Show(" 用DllImport 调用DLL 中的count 函数,\n传入的实参为10 ,得到的结果是:"+count(10).ToString()+"\n 结果可不是想要的11 哦!!!"," 挑战杯");MessageBox.Show(" 所得结果表明:\n 用DllImport 调用DLL 中的非托管\n 函数是全局的、静态的函数!!!"," 挑战杯");5)把Count.dll复制到项目“Tzb”的bin\Debug文件夹中,按“F5”运行该程序,并点击按钮B2,便弹出如下三个提示框:第1个提示框显示的是调用“count(0)”的结果,第2个提示框显示的是调用“count(10)”的结果,由所得结果可以证明“用DllImport调用DLL中的非托管函数是全局的、静态的函数”。
所以,有时候并不能达到我们目的,因此我们需要使用下面所介绍的方法:C#动态调用DLL中的函数。
3.C#动态调用DLL中的函数因为C#中使用DllImport是不能像动态load/unload assembly那样,所以只能借助API函数了。
在kernel32.dll中,与动态库调用有关的函数包括[3]:①LoadLibrary(或MFC 的AfxLoadLibrary),装载动态库。
②GetProcAddress,获取要引入的函数,将符号名或标识号转换为DLL内部地址。
③FreeLibrary(或MFC的AfxFreeLibrary),释放动态链接库。
它们的原型分别是:HMODULE LoadLibrary(LPCTSTR lp);FARPROC GetProcAddress(HMODULE hModule, LPCWSTR lpProcName);BOOL FreeLibrary(HMODULE hModule);现在,我们可以用IntPtr hModule=LoadLibrary(“Count.dll”);来获得Dll的句柄,用IntPtr farProc=GetProcAddress(hModule,”_count@4”);来获得函数的入口地址。
但是,知道函数的入口地址后,怎样调用这个函数呢?因为在C#中是没有函数指针的,没有像C++那样的函数指针调用方式来调用函数,所以我们得借助其它方法。
经过研究,发现我们可以通过结合使用System.Reflection.Emit及System.Reflection.Assembly里的类和函数达到我们的目的。
为了以后使用方便及实现代码的复用,我们可以编写一个类。
object[] Parameters = new object[]{(int)0}; // 实参为0Type[] ParameterTypes = new Type[]{typeof(int)}; // 实参类型为intModePass[] themode=new ModePass[]{ModePass.ByValue}; // 传送方式为值传Type Type_Return = typeof(int); // 返回类型为int// 弹出提示框,显示调用myfun.Invoke 方法的结果,即调用count 函数MessageBox.Show(" 这是您装载该Dll 后第"+myfun.Invoke(Parameters,ParameterTypes,themode,Type_Return).ToString() +" 次点击此按钮。
"," 挑战杯");5.“Form1.cs[设计]”视图中双击按钮B5,在“B5_Click”方法体内添加如下代码:myfun.UnLoadDll();6.按“F5”运行该程序,并先点击按钮B3以加载“Count.dll”,接着点击按钮B4三次以调用3次“count(0)”,先后弹出的提示框如下:这三个提示框所得出的结果说明了静态变量S 经初始化后,再传入实参“0”也不会改变其值为“0”。
7.点击按钮B5以卸载“Count.dll”,再点击按钮B3进行装载“Count.dll”,再点击按钮B4查看调用了“count(0)”的结果:从弹出的提示框所显示的结果可以看到又开始重新计数了,也就是实现了DLL的动态装载与卸载了。
(三)调用托管DLL一般方法C# 调用托管DLL是很简单的,只要在“解决方案资源管理器”中的需要调用DLL的项目下用鼠标右击“引用”,并选择“添加引用”,然后选择已列出的DLL或通过浏览来选择DLL文件,最后需要用using 导入相关的命名空间。
三、结论使用DLL有很多优点,如:节省内存和减少交换操作;开发大型程序时可以把某些模块分配给程序员,程序员可以用任何一门他所熟悉的语言把该模块编译成DLL文件,这样可以提高代码的复用,大大减轻程序员的工作量。
当然DLL也有一些不足,如在提要中提及的问题。
所以,如何灵活地调用DLL应该是每位程序员所熟知的。
C# 语言有很多优点,越来越多的人开始使用它来编程。
但是,C#还有一些不足,如对不少的底层操作是无能为力的,只能通过调用Win32 DLL 或C++等编写的DLL;另外,一般认为C#程序的保密性不够强,因为它容易被Reflector 反编译而得到部分源码,所以需要使用混合编程加强C#程序的保密性,而把DLL嵌入C#程序并实现动态调用的方法是比较理想的方法,因为可以把DLL文件先用某一算法进行加密甚至压缩后再作为资源文件添加到C#程序中,在程序运行时才用某一算法进行解压解密后才进行加载,所以即使用反编译软件,也只能得到一个资源文件,且这个资源文件是用一个复杂算法进行加密过的,不可能再次对资源文件中的内容进行反编译,从而大大加强了代码的保密性。