【问题标题】:vb6 dll In DelphiDelphi中的vb6 dll
【发布时间】:2016-05-23 05:14:28
【问题描述】:

我用这段代码写了一个 VB6 dll

Public Function RegGetStr(ByRef FullLocation_Name As String) As String
   Dim oReg As Object
    Set oReg = CreateObject("WScript.Shell")
    RegGetStr = oReg.RegRead(FullLocation_Name, "REG_SZ")

    Set oReg = Nothing
End Function

在德尔福我有图书馆工作

type
          TRegGetStr = Function(Const FullLocation_Name: String): String; StdCall;
    var
     aRegGetStr: TRegGetStr;

和

 @aRegGetStr := Windows.GetProcAddress(LibHandle, 'RegGetStr');

我遇到了崩溃 是因为我使用的字符串类型吗?还是别的什么?

【问题讨论】:

  • 是的,您的 Delphi 模块无法使用该代码,因为字符串类型对于互操作无效。
  • 当然你可以从你的 Delphi 代码中读取注册表。你真的应该停止在 VB6 中编写新代码。你错过了备忘录吗?
  • IIRC,在 VB6 中,您可以与 PAnsiChar 互操作字符串,因此它可能应该类似于:TRegGetStr = procedure(FullLocation_Name: PAnsiChar; Result: PAnsiChar) stdcall;,在 VB 端:Public Function RegGetStr(ByVal FullLocation_Name As String, ByVal Result As String),但我不完全确定。不过你应该试试。见here。
  • VB 不是像 VBA 一样支持 ActiveX 吗?也许可以使用 COM BSTR aka Delphi WideString?或 OleString ?
  • 我见过的大多数例子都是用 C 语言编写并由 VB6 使用的 DLL。这:'void __export CALLBACK GetDiskInfo (char *cDrive, char *szVolumeName, unsigned long *ulFreeSpace)` 被转换为Declare Sub getdiskinfo Lib "c:\somepath\diskinfo.dll" (ByVal mydrive As String, ByVal myvolume As String, free As Long)。反之亦然。

标签: delphi vb6


【解决方案1】:

您的问题是关于从 Delphi 调用 VB DLL。 开箱即用的 VB6 创建 ActiveX dll(创建为 ActiveX DLL 项目) How can I create a standard DLL in VB6? 看看那里描述 ActiveX DLL 的答案。

虽然您可以在 VB6 中创建标准 DLL,但您必须进行探索。它不支持开箱即用,不推荐。

您可以像使用 Delphi 中的任何 ActiveX dll 一样使用该 VB ActiveX DLL。
Deplhi Import Component - Type Library vs ActiveX

=====

另一方面,如果您尝试调用外部 DLL(例如用 Delphi 编写)FROM VB 应用程序,您将使用字符串的 pAnsiChar 参数创建 Delphi 函数。例如:在 MyDelProcs.dll 中:

procedure MyDelProc(pStr1: pAnsiChar, MyInt: integer);stdcall;
  .......................
exports
  MyDelProc;

在 VB 方面,您可以将过程声明为

Declare Sub MyDelProc Lib "MyDelProcs.dll" (ByVal sStr1 as String, MyLong As Long)

然后调用过程

   Call MyDelProc(sStr1, MyLong)

一些注意事项:

  1. sStr1 是 VB 内部的 Unicode,但在调用时被转换为 AnsiString。 ansistring 在末尾添加了一个 chr(0) 并移动到一个缓冲区,该缓冲区是 ansistring 的长度加上 chr(0)。

  2. 注意其他参数类型。 VB默认Integer为2字节,Delphi默认整数为4,相当于VB中的Long类型。

  3. 如果您的 Delphi 函数需要知道长度,请将其作为另一个(长/整数)参数传递。

  4. 字符串缓冲区的大小是固定的。如果您要返回一个长度较长的字符串,则要么用足够的空间填充原始字符串,要么传递一个具有足够长度的更长的虚拟​​字符串以供返回。

  5. 返回时,字符串被视为 ansistring。它将被转换回 Unicode 以放入 VB 内部字符串中。

【讨论】:

  • 所以不允许我对问题添加评论,所以我会在这里添加评论。 VB 字符串在底层是 Unicode,但作为 ansistring 从外部传递。当调用外部 DLL 的 from VB 时,就是这种情况。在这种情况下,Rudy 描述的调用是正确的。当用 VB 创建要从 Delphi 调用的 DLL 时,情况有所不同。您可以创建在进程内或进程外 ActiveX(作为 EXE)中运行的 ActiveX 接口。有一些不受支持的方法可以将 VB 作为直接 DLL 调用,我不推荐,但它们涉及启动 VB 块进行初始化。
  • 谁是提出 ActiveX 的傻瓜,我正在制作 VB6 *.DLL,仅此而已,请正确阅读问题,Rudy Velthuis 感谢您的评论,我从没想过使用字符串指针但我认为在 Delphi 中作为 PChar 接收可能会更好。我只想让 Delphi 和 VB6 之间的通信正确。我在 VB6 上安装了 InteropFormToolsInstaller,但这有什么变化。 Delphi 的 String 应该收集一个 VB ansi 字符串。
  • Dan Barcaly 谢谢我想让 Delphi 从 Delphi 的资源中删除 dll 并加载库以使项目可移植。 dll 功能在 VB6 中似乎很容易使用。
  • 我在徘徊,如果 Rudy Velthuis 的想法和使用从 Delphi 分配的内存而不是 dll 将是一个出路。
  • 谁是提出 ActiveX 的傻瓜?微软。我在这里指出了这一点。如果这冒犯了你,对不起,只是指出事实。标准 DLL 很容易在 VB6 中使用,这是真的。我一直都这样做。但我将您的问题理解为将 VB6 创建的 DLL 与 Delphi 应用程序一起使用。那是完全不同的,您需要使用 ActiveX 或者您需要查看用于创建 DLL 的不受支持/未记录的方法。有(或者是,我最近没有看过)将 VB6 函数公开为 DLL 的第 3 方工具。我没用过,只听说过。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-19
  • 1970-01-01
  • 1970-01-01
  • 2011-12-01
  • 1970-01-01
相关资源
最近更新 更多