在vc++中为vb4.0创建一个DLL

Create a DLL in VC++ for VB 4.0

本文关键字:一个 DLL 创建 vc++ 中为 vb4      更新时间:2023-10-16

我正在Visual c++ 1.5中创建一个DLL,用于Visual Basic 4.0(我正在16位Windows 95上工作)。我创建的一个函数接收一个字符串并返回另一个字符串,参数声明为:

NPSTR CALLBACK __ export (NPSTR chain)
{
    ....
}

我还测试了LPSTR和char *。

在Visual Basic中,do的语句作为字符串使用ByVal参数作为字符串函数,但vc++不接收链,当我运行VB程序时,给我一个错误,说类型不匹配。

接收一个Visual Basic字符串并返回另一个字符串的正确声明语句是什么?当我返回整个步骤时,没有任何问题。我还想知道传递数组的方式是什么。

除了"如何声明这样一个函数"的问题,你的DLL函数的问题是,它应该返回一个字符串从DLL,除非它是一个指针的原始字符串传递。

大多数(如果不是所有的话)处理字符串的Windows API函数都是这样做的:

  1. DLL函数的调用者负责创建字符串/缓冲区,包括在调用函数之前使其大小合适。

  2. 调用者提供另一个参数,传递的缓冲区的最大长度

在DLL端,DLL做如下操作:

  1. DLL函数从一个本地字符串变量(可以是字符数组,std::string,没关系,因为这是DLL内部的)中获取请求的信息。

  2. DLL函数然后将这个字符串信息复制到传入的缓冲区中,根据传入的调用者给出的最大大小。因此,如果字符串信息实际上是1,000字节,但用户传递了100作为最大缓冲区大小,那么您只复制99(或100)个字符。

  3. DLL函数返回复制的字符数。如果发现原始传入的缓冲区很大,调用者可以使用它来将其缓冲区大小调整为实际大小(注意,处理终止NULL是您必须在函数的调用者和DLL函数之间达成的协议,因此我在这里没有详细说明您是否应该在最后复制NULL。)

  4. 此外,DLL还可以返回存储整个字符串信息所需的字符总数。通常为了发生这种情况,DLL函数有一个特殊的"模式",如果输出字符串为NULL,它可以工作。如果输出字符串为NULL, DLL函数仍然会获取信息,但不会将其复制到输出缓冲区,而是返回字符总数。因此,调用者将对DLL函数进行两次调用,一次确定信息的字符数,以便调用者相应地调整其缓冲区的大小,而对DLL函数的第二次调用将是将字符复制到缓冲区的实际调用。

这就是它的工作原理。如果您的函数需要输入字符串和输出字符串,那么您的函数应该更改为如下内容:

LONG CALLBACK __ export SomeDLLFunction(NPSTR strIn, NPSTR strOut, LONG maxOutSize)

现在在VB这边:

Public Declare Function SomeDLLFunction Lib "YourDLL" (ByVal strIn As String, ByVal strOut As String, ByVal strMaxLen As Long) As Long

现在,为什么Windows这样做的原因是DLL函数不再返回指向局部变量的指针或引用(这是未定义的行为),并且不再需要弄清楚如何动态创建字符串(然后需要一些模块来释放字符串,并且还确切地知道如何释放字符串,即调用什么函数来完成此操作-这是一个痛苦的脖子)。

一切都依赖于调用者提供的缓冲区和写入缓冲区的最大大小

GetHostByName函数为例:

// C
struct hostent* FAR gethostbyname(
  _In_  const char *name
);
// VB
Public Declare Function gethostbyname 
    Lib "ws2_32.DLL" (ByVal host_name As String) As Long

你可以使用:

const char* CALLBACK __ export (const char* chain)
{
    ....
}

和在VB中的声明:

// VB
Public Declare Function functionname 
    Lib "yourdll.DLL" (ByVal chain As String) As String