有两个部分说明了每种技术: C Visual Basic 代码中的声明函数和 C 的内部函数过程的数据被传递、 修改或发回。将一个字符串传递到 C DLL声明用于 C 函数必须使用 c ByVal 来接收一个字符串。C 函数通常需要结束"空值字符"(二进制零) 的字符串。当声明函数的参数使用 ByVal 时,这会告诉 Visual Basic 以空值终止的字符串形式传递字符串。因此,声明如下所示: Declare Sub passOneString Lib "mydll.dll" (ByVal lpszBuf As String)
实际的 C 函数如下所示: void __far __pascal __export passOneString(char __far *lpszBuf)
实际的内部机制的 C 函数是简单而它将接收到的参数作为标准 C 字符串。注意: 两个"pascal"和"远"是编译器特定的关键字所允许的 ANSI 标准。它们应具有适当数量的下划线,若要将它们放在适当的名称空间。最新的编译器,严格遵循标准并说出您需要两个下划线 (但允许较少的向后兼容性)。某些以前的 Microsoft 编译器只允许使用 0 或 1 的下划线。传递 (和修改) c DLL 的字符串数组演示此方法的函数声明不使用 ByVal。原因传递的数组,该声明需要将字符串数组传递给该函数使用内部 Visual Basic 数组说明符 (HAD)。因此,声明如下所示: Declare Sub passStrings Lib "mydll.dll" (theArray() As String, ByVal nIndex% )
实际的 C 函数如下所示: void __far __pascal __export passStrings(HAD had, int nIndex)
VBArrayElement() 用于提取 Visual Basic 字符串的函数从数组 (使用由 nIndex 指定数组中的索引) 处理 (HLSTR)。VBGetHlstr() 将转换该字符串句柄,然后到标准 C 字符串。如果您希望,如果用于接收字符串缓冲区和足够大,所做的更改,则可以修改该 C 字符串随意。但是,修改后的字符串必须存储在原始的 Visual Basic 字符串句柄。这是通过 VBSetHlstr() 函数。从 C DLL 中函数返回一个字符串Visual Basic 例程从函数接收一个字符串,该函数必须返回一个字符串,并在 C 中侧边、 返回类型为 HLSTR 的变量声明。因此,声明如下所示: Declare Function returnAString Lib "mydll.dll" () As String
实际的 C 函数如下所示: hlstr __far __pascal __export returnAString()
这一次,VBCreateTempHlstr 用来转换指定的标准 C 字符串到 Visual Basic 字符串句柄。然后该函数只返回该句柄,以字符串的形式接收 Visual Basic。此外,VBRuntimeError 函数用于生成 Visual Basic 运行时错误。如果在调用 VBCreateTempHlstr 后存在的错误条件,VBRuntimeError 设置 Visual Basic 错误代码,然后退出函数。出于此原因,此函数只应由 Visual Basic,不在控件的过程中自定义控件或 Windows 本身在调用代码的其他位置的直接调用的例程中。若要创建 DLL 的分步示例以下是生成 DLL 使用 Visual C++ 所需的步骤:- 启动 Visual C++。
- 通过从项目菜单中选择新建来创建一个新的项目。选择以下选项:
- 将项目类型设置为"Windows 动态链接库 (。DLL)"。
- 清除"使用 Microsoft 基础类"复选框。
- 创建一个新文件,添加以下文本并将它另存为"MYDLL。DEF":
LIBRARY MYDLL DESCRIPTION "String Manipulation DLL" EXETYPE WINDOWS 3.1 CODE PRELOAD MOVEABLE DISCARDABLE DATA PRELOAD MOVEABLE SINGLE HEAPSIZE 4096 EXPORTS passOneString @1 passStrings @2 returnAString @3 - 创建一个新文件、 添加下面的代码,并将它另存为"MYDLL。C":
#include <windows.h> #include <string.h> #include <stdio.h> #include "vbapi.h" #define USHORT unsigned short //------------------------------------------------------------------- // Global Variables //------------------------------------------------------------------- HANDLE hmodDLL; //------------------------------------------------------------------- // Receive a single string in functions argument list: // display string to user //------------------------------------------------------------------- void __far __pascal __export passOneString(LPSTR lpszBuf) { // Display old string to user. MessageBox( NULL, lpszBuf, "Inside DLL... (unmodified)", 0 ); } //------------------------------------------------------------------- // Receive/modify array of strings in functions argument list: // - Retrieve a specified element in an array of strings. // - Transform that element into a standard C string. // - Modify that standard C string. // - Save the modified string back into the original element of the // array. //------------------------------------------------------------------- void __far __pascal __export passStrings(HAD had, int nIndex) { HLSTR hlstr; // Reference to VB string int idx[1]; // Array in one dimension char lpszBuf[255]; // "Std C" string buffer USHORT cbCount; // # of characters in string // Retrieve a specified element (nIndex) in an array of strings. idx[0] = nIndex; hlstr = VBArrayElement(had, 1, (LPINT)idx); // Transform that element into a standard C string. cbCount = VBGetHlstr( hlstr, lpszBuf, sizeof( lpszBuf ) - 1 ); // Display old string to user. MessageBox( NULL, lpszBuf, "Inside DLL... (unmodified)", 0 ); // Modify that standard C string. wsprintf(lpszBuf, "%s <-- size = %d", lpszBuf, lstrlen(lpszBuf)); // Save the modified string in the original element of the array. VBSetHlstr( &hlstr, lpszBuf, lstrlen( lpszBuf ) ); } //------------------------------------------------------------------- // Return a string from a function back to a Visual Basic program: // - Create Hlstr from standard C string. // - Report error (if any). // - Return Hlstr to calling VB function. //------------------------------------------------------------------- HLSTR __far __pascal __export returnAString() { HLSTR temp; char *buff = {"This function returns a string from a DLL."}; // Creates Hlstr from standard C string. temp = VBCreateTempHlstr(buff, lstrlen(buff)); // Report error (if any). if (HIWORD(temp) == -1) VBRuntimeError(LOWORD(temp)); // Return Hlstr to calling VB function. return temp; } //------------------------------------------------------------------- // Initialize library. // This routine is called from the DLL entry point in LIBINIT.ASM, // which is called when the first client loads the DLL. //------------------------------------------------------------------- BOOL FAR PASCAL LibMain(HANDLE hmod, HANDLE segDS, USHORT cbHeapSize) { // Avoid warnings on unused (but required) formal parameters. cbHeapSize = cbHeapSize; segDS = segDS; hmodDLL = hmod; // Leave the DS unlocked when not running. // Required only under Windows version 3.1 // Win32 does not require or support UnlockData() UnlockData( 0 ); return TRUE; } //------------------------------------------------------------------- // Handle exit notification from Windows. // This routine is called by Windows when the library is freed // by its last client. //------------------------------------------------------------------- VOID __far __pascal __export WEP (BOOL fSystemExit) { // Avoid warnings on unused (but required) formal parameters. fSystemExit = fSystemExit; }
- 从项目菜单中,选择生成 MYDLL。DLL 的选项。
- 添加 MYDLL。定义,MYDLL。C 和 \VB\CDK\VBAPI。LIB 文件复制到项目。本示例假定已安装 Visual Basic 到 \VB 目录中。否则,请修改此为正确的路径的最后一个条目。
若要创建 Visual Basic 应用程序使用 DLL 的分步示例- 在 Visual Basic 中开始一个新项目。默认情况下,将创建 Form1。
- 在 Form1 中放置三个命令按钮 (Command1 和 Command2,Command3)。
- 作为指导,使用下表设置第 2 步中添加的控件的属性。
Control name Property New value --------------------------------------------- Command1 Caption &Pass a String Command2 Caption Pass &And Modify Array Command3 Caption &Receive a String - 将下面的代码添加到 Form1 的常规 (声明) 部分中:
' Enter each of the following Declare statements as one, single line: Declare Sub passOneString Lib "mydll.dll" (ByVal lpszBuf As String) Declare Sub passStrings Lib "mydll.dll" (theArray() As String, ByVal nIndex%) Declare Function returnAString Lib "mydll.dll" () As String
- 将下面的代码放在 Command1 单击事件过程中:
Sub Command1_Click () Dim MyStr As String * 80 Dim My2ndStr$ MyStr = "Hello World (First String)" My2ndStr$ = "Hello World Again (Second String)" Call passOneString(MyStr) Call passOneString(My2ndStr$) End Sub
注意: 此示例演示定义的字符串的任何一种方法同样适用很好地。 - 将下面的代码放在 Command2 单击事件过程中:
Sub Command2_Click () Dim i% ReDim array(0 To 2) As String array(0) = "Short" array(1) = "Medium Medium" array(2) = "Long Longer Longest" For i% = 0 To 2 Call passStrings(array(), i%) MsgBox array(i%), 0, "Inside VB... (modified)" Next i% End Sub
- 将下面的代码放在 Command3 单击事件过程中:
Sub Command3_Click () Dim MyStr$ MyStr$ = returnAString() MsgBox MyStr$, 0, "Returned from DLL..." End Sub
- 若要运行该程序运行菜单中选择启动。
评论这张
转发至微博
转发至微博
|