下面的delphi代码有点问题,恳请各位高手帮忙解决

下面的delphi代码有点问题,恳请各位高手帮忙解决,第1张

c++中共有两种库:

1、LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library。(这种方式更灵活,写的程序体积小,但是需要exe和dll同时发布)

2、LIB包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库static link library。(这种方式不是很灵活,因为lib被编译到exe中,写出的程序体积大,但是只需要发布exe即可,不需要dll文件)

共有两种链接方式:

1、动态链接使用动态链接库,允许可执行模块(dll文件或exe文件)仅包含在运行时定位DLL函数的可执行代码所需的信息。

2、静态链接使用静态链接库,链接器从静态链接库LIB获取所有被引用函数,并将库同代码一起放到可执行文件中。

关于lib和dll的区别如下:

(1)lib是编译时用到的,dll是运行时用到的。如果要完成源代码的编译,只需要lib;如果要使动态链接的程序运行起来,只需要dll。

(2)如果有dll文件,那么lib一般是一些索引信息,记录了dll中函数的入口和位置,dll中是函数的具体内容;如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。使用静态编译的lib文件,在运行程序时不需要再挂动态库,缺点是导致应用程序比较大,而且失去了动态库的灵活性,发布新版本时要发布新的应用程序才行。

(3)动态链接的情况下,有两个文件:一个是LIB文件,一个是DLL文件。LIB包含被DLL导出的函数名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到DLL文件。在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中相应函数代码的地址,从而节省了内存资源。DLL和LIB文件必须随应用程序一起发行,否则应用程序会产生错误。如果不想用lib文件或者没有lib文件,可以用WIN32 API函数LoadLibrary、GetProcAddress装载。

(静态连接)使用lib需注意两个文件:

(1)h头文件,包含lib中说明输出的类或符号原型或数据结构。应用程序调用lib时,需要将该文件包含入应用程序的源文件中。

(2)LIB文件,略。

(动态连接)使用dll需注意三个文件:

(1)h头文件,包含dll中说明输出的类或符号原型或数据结构的h文件。应用程序调用dll时,需要将该文件包含入应用程序的源文件中。

(2)LIB文件,是dll在编译、链接成功之后生成的文件,作用是当其他应用程序调用dll时,需要将该文件引入应用程序,否则产生错误。如果不想用lib文件或者没有lib文件,可以用WIN32API函数LoadLibrary、GetProcAddress装载。

(3)dll文件,真正的可执行文件,开发成功后的应用程序在发布时,只需要有exe文件和dll文件,并不需要lib文件和h头文件。

使用lib的方法:

静态lib中,一个lib文件实际上是任意个obj文件的集合,obj文件是cpp文件编译生成的。在编译这种静态库工程时,根本不会遇到链接错误;即使有错,也只会在使用这个lib的EXT文件或者DLL工程里暴露出来。

在VC中新建一个static library类型的工程Lib,加入testcpp文件和testh文件(头文件内包括函数声明),然后编译,就生成了Liblib文件。

别的工程要使用这个lib有两种方式:

(1)在project->link->Object/Library Module中加入Liblib文件(先查询工程目录,再查询系统Lib目录);或者在源代码中加入指令#pragma comment(lib, “Liblib”)。

(2)将Liblib拷入工程所在目录,或者执行文件生成的目录,或者系统Lib目录中。

(3)加入相应的头文件testh。

使用DLL的方法:

使用动态链接中的lib,不是obj文件的集合,即里面不会有实际的实现,它只是提供动态链接到DLL所需要的信息,这种lib可以在编译一个DLL工程时由编译器生成。

创建DLL工程的方法(略)。

(1)隐式链接

第一种方法是:通过project->link->Object/Library Module中加入lib文件(或者在源代码中加入指令#pragma comment(lib, “Liblib”)),并将dll文件置入工程所在目录,然后添加对应的h头文件。

#include "stdafxh"

#include "DLLSampleh"

#pragma comment(lib, "DLLSamplelib") //你也可以在项目属性中设置库的链接

int main()

{

TestDLL(123); //dll中的函数,在DllSampleh中声明

return(1);

}

(2)显式链接

需要函数指针和WIN32 API函数LoadLibrary、GetProcAddress装载,使用这种载入方法,不需要lib文件和h头文件,只需要dll文件即可(将dll文件置入工程目录中)。

#include <iostream>

#include <windowsh> //使用函数和某些特殊变量

typedef void (DLLFunc)(int);

int main()

{

DLLFunc dllFunc;

HINSTANCE hInstLibrary = LoadLibrary("DLLSampledll");

if (hInstLibrary == NULL)

{

FreeLibrary(hInstLibrary);

}

dllFunc = (DLLFunc)GetProcAddress(hInstLibrary, "TestDLL");

if (dllFunc == NULL)

{

FreeLibrary(hInstLibrary);

}

dllFunc(123);

std::cinget();

FreeLibrary(hInstLibrary);

return(1);

}

LoadLibrary函数利用一个名称作为参数,获得DLL的实例(HINSTANCE类型是实例的句柄),通常调用该函数后需要查看一下函数返回是否成功,如果不成功则返回NULL(句柄无效),此时调用函数FreeLibrary释放DLL获得的内存。

GetProcAddress函数利用DLL的句柄和函数的名称作为参数,返回相应的函数指针,同时必须使用强转;判断函数指针是否为NULL,如果是则调用函数FreeLibrary释放DLL获得的内存。此后,可以使用函数指针来调用实际的函数。

最后要记得使用FreeLibrary函数释放内存。

注意:应用程序如何找到DLL文件?

使用LoadLibrary显式链接,那么在函数的参数中可以指定DLL文件的完整路径;如果不指定路径,或者进行隐式链接,Windows将遵循下面的搜索顺序来定位DLL:

(1)包含EXE文件的目录

(2)工程目录

(3)Windows系统目录

(4)Windows目录

(5)列在Path环境变量中的一系列目录

// DllSample2h : Defines the export functions and classes

int _declspec(dllexport) Add(int a,int b);

void _declspec(dllexport) ShowString();

// DllSample2cpp : Defines the entry point for the DLL application

// Non-MFC DLLs的编写示例

// Non-MFC DLL:指的是不用MFC的类库结构,直接用C语言写的DLL,其输出

// 的函数一般用的是标准C接口,并能被非MFC或MFC编写的应用程序所调用

//

#include "DllSample2h"

#include "stdafxh"

/

这是一个输出函数的例子

在输出函数或类的申明中用到_declspec(dllexport),

这是VC提供的一个关键字,用它可在动态连接库中输出一个数据、

一个函数或一个类。用这个关键字可省不少事,不用在DEF文件

中说明要输出这个类、那个函数的

函数说明:略

参数说明:略

/

int _declspec(dllexport) Add(int a,int b)

{

return (a+b);

}

void _declspec(dllexport) ShowString()

{

printf("Nice to see you,I suceed!");

}

/

这是一个输出类的示例。

也用到了_declspec(dllexport)关键字

/

class _declspec(dllexport) Easy

{

// add your class definition here

// to avoid complexity,I omit the implementation here

/ // constructor and destructor

public:

Easy();

~Easy();

// data members

private:

int m_ID;

char m_Name[24];

// member functions

public:

char ToString();

char GetID();

int GetName();

/

};

/

函数说明:

每一个DLL必须有一个入口点,这就象我们用C编写的应用程序一样,

必须有一个WINMAIN函数一样。在这个示例中, DllMain是一个缺省的

入口函数,你不需要编写自己 的DLL入口函数,并用linker的命令行

的参数开关/ENTRY声明。用这个缺省的入口函数就能使动态连接库被

调用时得到正确的初始化

参数说明:

@hMoudle是动态库被调用时所传递来的一个指向自己的句柄

(实际上,它是指向_DGROUP段的一个选择符)

@ul_reason_for_call是一个说明动态库被调原因的标志。当进程或线程

装入或卸载动态连接库的时候, *** 作系统调用入口函数,并说明动态连接库

被调用的原因。它所有的可能值为:

DLL_PROCESS_ATTACH: 进程被调用

DLL_THREAD_ATTACH: 线程被调用

DLL_PROCESS_DETACH: 进程被停止

DLL_THREAD_DETACH: 线程被停止

@lpReserved是一个被系统所保留的参数。

/

BOOL APIENTRY DllMain( HANDLE hModule,

DWORD ul_reason_for_call,

LPVOID lpReserved

)

{

switch( ul_reason_for_call )

{

case DLL_PROCESS_ATTACH:

// add your own hadling code here

break;

case DLL_THREAD_ATTACH:

// add your own hadling code here

break;

case DLL_THREAD_DETACH:

// add your own hadling code here

break;

case DLL_PROCESS_DETACH:

// add your own hadling code here

break;

}

return TRUE;

}

/

ps 调用DLL的方法:

(1)显式的调用

所谓显式的调用,是指在应用程序中用LoadLibrary或MFC提供的

AfxLoadLibrary显式的将自己所做的动态连接库调进来,动态连接库

的文件名即是上两函数的参数,再用GetProcAddress()获取想要引入

的函数。自此,你就可以象使用如同本应用程序自定义的函数一样来

调用此引入函数了。在应用程序退出之前,应该用FreeLibrary或

MFC提供的AfxFreeLibrary释放动态连接库。

(2)隐式的调用

隐式的调用则需要把产生动态连接库时产生的LIB文件加入到应

用程序的工程中,想使用DLL中的函数时,只须说明一下。隐式调

用不需要调用LoadLibrary()和FreeLibrary()

比较:由此看来,隐式说明调用的方法比较简单,但DLL改变后,应用程序

须重新编译。并且,所有被调用的DLL在应用程序加载的同时被加载到内

存中,但应用程序调用的DLL比较多时,装入的过程十分慢。隐式的调用

则在应用程序不知道所要装入的DLL,或显式调用不成功时,允许用户指定

所要加载的动态连接库,比较灵活

/

/

==================Associated MSDN Documents========================

Dynamically Loading and Invoking DLLs

GetProcAddress

/

--------------------------------------------------------------------------------------- 这是C#文件,希望使用Dll,API调用成功,但是我的Dll,:`(

// This's a Example of using vc DLL in C# environment

// Also the calling of WINDOWS API is displayed here

// basic prequisite

using System;

// this is required if you want to use DLL

using SystemRuntimeInteropServices;

// package the Apis in a class,haha

public class WinAPIImport

{

// this is the example of calling APIs in systematic DLLs

// just an example,don't mind the messy invokation

[DllImport("gdi32dll")]

static public extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

[DllImport("wsnmp32")] public static extern int SnmpCleanup();

[DllImport("dllsample2")] public static extern void ShowString();

[DllImport("dllsample2")] public static extern int Add(int a,int b);

}

namespace UsingDllSample00

{

/// <summary>

/// Class1 的摘要说明。

/// </summary>

class Class1

{

/// <summary>

/// 应用程序的主入口点。

/// </summary>

[STAThread]

static void Main(string[] args)

{

// no need to create a WinAPIImport object to invoke extern funtions

// first, display the calling of Win32 API(s)

/1/ WinAPIImportSnmpCleanup();

// second, show how to use functions in

/2/ WinAPIImportAdd(2,3);

/3/ WinAPIImportShowString();

ConsoleWriteLine("Look,the functions in DLL are called!:)");

}

}

}

以上就是关于下面的delphi代码有点问题,恳请各位高手帮忙解决全部的内容,包括:下面的delphi代码有点问题,恳请各位高手帮忙解决、C# 怎么把其他应用程序集成到当前项目、windows中LIB和DLL的区别与使用等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9693776.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-01
下一篇2023-05-01

发表评论

登录后才能评论

评论列表(0条)

    保存