使用DLL与PHP的入门指南

19
我有一个项目需要用PHP访问一个DLL。服务器是Windows机器,Apache服务器由XAMPP提供。
我在网上看到了多个答案,如:
- [使用DLL在PHP中](link1) - [PHP与DLL通信](link2) - [通过PHP调用DLL](link3) - [PHP中的COM类](link4) - [PHP的W32API扩展](link5) - [如何加载COM DLL文件](link6)
这是我在HTA / Javascript中调用DLL的方法: 有人有一个可行的示例吗?
这是我在PHP中尝试过的方法:
$obj = new COM('pathTo.dll');

关于DLL的信息:
1. 使用Delphi编译 2. 它是(当然)自制的 3. 当我尝试使用regsvr32注册DLL时,出现以下错误:“找不到DllRegisterServer入口点” 4. 它可以在不使用regsvr32注册的情况下使用吗?

你的COM类的CLSID是什么?我怀疑你没有创建一个准备好进行COM互操作的DLL... - Thorsten Dittmar
@ThorstenDittmar CLSID 是一个字符串 AlphaNumeric 字符串,格式如下:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX。你所说的“准备好用于 COM 互操作的 DLL”是什么意思? - David Laberge
@DavidLaberge CLSID(我认为)在技术上是一个UUID,在这种情况下使用时可能需要用 {} 括起来。 - DaveRandom
根据我在链接和你的问题中看到的,你必须将你的DLL注册到系统中,并注册一个COM类,然后才能从PHP中使用它。如果你没有这样做,它是无法工作的。 - Thorsten Dittmar
@Hossein 谢谢,但是它可以不用通过 regserv32 注册来使用吗? - David Laberge
显示剩余4条评论
4个回答

16

创建DLL文件时需要使用一个模块定义文件。它将包含类似于这样的内容:

;
;contains the list of functions that are being exported from this DLL
;

DESCRIPTION     "Simple COM object"

EXPORTS
                DllGetClassObject       PRIVATE
                DllCanUnloadNow         PRIVATE
                DllRegisterServer       PRIVATE
                DllUnregisterServer     PRIVATE

这个定义允许regsvr32找到DllRegisterServer入口点。

另一个选项是尝试向regsvr32传递/n标志。

Regsvr32 [/u] [/n] [/i[:cmdline]] dllname

/u - 注销服务器

/i - 调用DllInstall并给它传递可选的[cmdline]; 与/u一起使用时调用dll卸载

/n - 不要调用DllRegisterServer; 必须与/i一起使用

/s – 静默运行; 不显示消息框(在Windows XP和Windows Vista中添加)

最终,在尝试让DLL与PHP配合工作之前,您需要确保您的DLL总体上能够正常工作。


1
修复损坏的链接模块定义文件 https://learn.microsoft.com/en-us/cpp/build/reference/module-definition-dot-def-files?view=msvc-170 - Moustafa Khalil

1

有了PHP>=7.4.0的新FFI/Foreign Function Interface(在此问题发布时还不存在),这比以往任何时候都更容易!例如,要从kernel32.dll调用GetCurrentProcessId();函数:

<?php

declare(strict_types=1);
$ffi = FFI::cdef(
    'unsigned long GetCurrentProcessId(void);',
    "C:\\windows\\system32\\kernel32.dll"
);
var_dump($ffi->GetCurrentProcessId());

输出

C:\PHP>php test.php
int(24200)

:)


1

我遇到了同样的问题,我修复了一些步骤:

  1. open the command line in administrator right (windows + r + type 'cmd') write the PATH where you're your dll file:
    C:\Windows\system32\regsvr32 xwizards.dll(it's example)
    a window show up with "DLLRegisterServer success"
  2. check your phpinfo() if you're com_dotnet extension
  3. now write into your PHP code :

        try    {
      $dll = new COM('<theNameOfDllFile>.<NameOfTheClass>'); //without extension '.dll' for theNameOfDllFile
      $dll->Function(); 
      } catch(Exception $e){
        echo 'error: ' . $e->getMessage(), "\n";}
    

    Now if you know how manage the class and the function of you're dll it's going ok,however no error massage should show up on your screen


如果我表达不清楚,请让我知道,下次我会尽力做得更好 :)

你能提供更多细节和一个可行的例子吗?我已经到了不再显示“无法打开文件”的地步。现在它只是说“类未注册”。所以我离解决方案更近了。我正在使用.NET dlls。 - Bitterblue
这种方法导致了一个错误:无法创建COM对象“dllName.dllClass”:语法无效。您能否就此错误的原因提供建议? - Jacob Collins

-2

Linux/Apache 服务器无法访问 DLL。因此,该项目被放弃。


1
服务器是一台Windows机器,Apache服务器由XAMPP提供。 - gadget00
这与Linux毫无关系。 - Gogowitsch
1
Wine项目可以在Linux上使用DLL,您可以通过PHP(shell_exec(),proc_open()等)调用Wine。 - hanshenrik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接