• 关于在Delphi中链接VC的obj文件(XE2以上版本)


         个人用的少的东西,笔记之,以作记录

         实际上老久之前,应该在Delphi中就可以链接使用Obj文件了吧,我用的第一个Delphi版本是D7,我记得他就可以了。至于再往前追述,就不晓得初始来源是哪个版本了。不过对于以前的版本的链接obj只能是OMF这个格式,这个格式是很早很早之前定义的一个文件格式,之后微软都转向了COFF这种格式了,也就是说VC编译出来的OBJ文件都是COFF格式。所以,以前要在Delphi中使用obj就要多走几步路程,要么使用VC编译的obj是COFF格式的,此时要使用COFF2OMF来进行转换,将COFF转换成OMF格式的,要么就是拿到C的源码,使用BCB等工具来编译以生成OMF的格式的obj。然后才能在Delphi中使用{$Link指令进行链接而使用里面的函数。

        今天早上,俺在群中偶然听到了Delphi XE2可以支持COFF的obj静态链接了。这也就是说,可以直接使用VC编译生成的Obj文件了。之后写了一个测试的Demo,很简单的函数

    #include "stdafx.h"

    extern "C" {
    extern int add(int x,int y);
    }

    int add(int x,int y)
    {
    return x+y;
    }

    编译生成了obj文件之后给Delphi使用,刚开始没改编译模式,生成的是Debug版本的obj文件,在Delphi中使用的时候,总是会报错误,无法发现add的前置引用,折腾了半天,也没搞好,之后编译成Release版本,在给Delphi使用,则运行成功!不知道是我搞的有问题还是说只能是Release版本可用,总之,发布Release的Obj给Delphi使用是没问题的。

    不过这个例子就比较过于简单了,没实际作用,如果真实在开发过程中,那复杂度肯定是天差地别,于是找了一个VC版的Hook库,相对来说,这个库的代码就比较多一些了,而且也引用了好些系统API,比较复合实际开发的目的。我找的这个Hook库是海风月影大大的库,可以从这里下载,编译生成Obj文件之后,拿到Delphi中使用,编译就报了未声名

    __imp__LoadLibraryA@4这样的错误,可见,这系统API在Obj中使用的,还不是真的将API函数的地址放入了,只是一个动态的预指定,于是编译的时候就找不到对应的函数了,所以我们需要在链接Obj的时候将这些导入函数在我们的程序中声名,比较蛋疼的是Delphi中的@是关键字,所以这个在VC的函数中,我们就需要将函数全部声名为C版本的函数导出和导入,C版本的会在函数名称前加入一个下划线,同时将WinApi的那套系统函数都在VC中写一个外置函数声名,API函数名字全部换掉,比如原来里面调用的是LoadLibrary这个是在Windows.h中声名的,我们现在不用这个,换一个声名

    extern HMODULE __cdecl LoadLibraryExEx(LPCSTR lpLibFileName);

    声名一个外部导入函数LoadLibraryExEx,然后将LoadLibrary都改成LoadLibraryExEx,同样道理,将API函数都做对应的处理之后编译

    然后在Delphi中再将这些函数作为这个obj的导入函数,

    function _LoadLibraryExEx(lpLibFileName: PAnsiChar): HMODULE;cdecl;
    begin
      Result := LoadLibraryA(lpLibFileName);
    end;

    这样包装一下,在进入链接Obj的时候,就会找到对应的函数了,搞定之后,还会发现,会报free的这个函数的错误,这个是VC的一个函数,函数在MSVCR70.DLL这个库中,所以也需要包装一下

    extern void   __cdecl free(void *);

    malloc这个函数一样,之后在Delphi中,需要引用到MSVCR70.DLL这个动态库

    procedure free(p: Pointer);cdecl;external 'MSVCR70.DLL';

    procedure _free(p: Pointer);cdecl;
    begin
      free(p);
    end;

    这样就OK了,编译程序,在用通过

    至于为何我要将VC中动态库的WINAPI都换成__cdecl的声名模式,可以自己去试一试,看看效果了!主要还是我前面说的Delphi中的@是一个关键字!

     当然,这个Free和malloc也可以不用他这个Dll中的函数,可以直接用Delphi的也可以

    比如

    function _malloc(size_t: DWORD): Pointer;cdecl;
    begin
      GetMem(Result,Size_t);
    end;

    procedure _free(p: Pointer);cdecl;
    begin
      FreeMem(p);
    end;

    这样就免去了外部DLL的东西了!

    源码下载

  • 相关阅读:
    Mvc Tree的简单应用
    nodeJs的学习之路(1)
    AngularJs基础学习指南(1)
    前端工程化讲解
    前端性能优化--为什么DOM操作慢?
    This package contains perl-5.16.3, java8, nifi-1.1.2 on ubuntu:14.04
    This package contains sshd, pcal, mysql-client on Ubuntu14:04
    This package contains mysql-server on ubuntu:14.04
    NIFI-创建一个FlowFile并利用PutFile保存到到指定目录
    NIFI如何利用eclipse开发自己的Processor(下)
  • 原文地址:https://www.cnblogs.com/DxSoft/p/2240980.html
Copyright © 2020-2023  润新知