VC9.0 Express下如何创建支持VB6的DLL,以及字符串传递
经典的教程可参考Edais的方法:
http://edais.mvps.org/Tutorials/CDLL/CDLLch1b.html
VC9.0 Express版本下并没有DLL的模板, 创建时通过下面几步实现:
1)在CPP文件中写函数代码, 例如:
2)新建一个文本文档, 命名为 [链接库名称].def, 不包括中括弧, 在该文件中添加以下内容:
Function1 ;在此添加函数名, 如果还有, 在下面继续添加
3)打开项目属性页, 将[常规]选项中的配置类型更改为DLL, 同时在[连接器]选项中, 添加第二步定义的文件名到[模块定义文件]
4)生成即可.
如何在C++和VB中传递字符串, 参考微软的帮助:http://support.microsoft.com/kb/187912
内容如下:
http://edais.mvps.org/Tutorials/CDLL/CDLLch1b.html
VC9.0 Express版本下并没有DLL的模板, 创建时通过下面几步实现:
1)在CPP文件中写函数代码, 例如:
int _stdcall Function1() {
return 1;
}
注意要使用_stdcall前缀, 且要放在返回值类型后, 函数名前. 此处不需要__declspec(dllexport), 如果添加的话, 有可能造成VB6下无法找到符号等错误.return 1;
}
2)新建一个文本文档, 命名为 [链接库名称].def, 不包括中括弧, 在该文件中添加以下内容:
LIBRARY [DLLName]
;注意不包括中括弧EXPORTS
Function1 ;在此添加函数名, 如果还有, 在下面继续添加
3)打开项目属性页, 将[常规]选项中的配置类型更改为DLL, 同时在[连接器]选项中, 添加第二步定义的文件名到[模块定义文件]
4)生成即可.
如何在C++和VB中传递字符串, 参考微软的帮助:http://support.microsoft.com/kb/187912
内容如下:
Code
用于 Visual Basic 创建 C 的动态链接库 (DLL) 时, 很重要要记住 C 和 Visual Basic 处理字符串方式不同。必须采取每个预防措施以确保正确地传递所有字符串,; 否则,可能会出现一个严重的错误。 这篇文章您展示如何编写函数,在作为参数接受字符串的 C DLL 以及如何从 Visual Basic 应用程序中调用导出的函数。
为了开发 C DLL,很重要,了解如何 Visual Basic 处理字符串在内部以了解如何在将传递给您的 DLL 函数。 大多数 C 函数需要字符串为空终止的 ASCII 字符数组。 但 Visual Basic 使用名为 BSTR 类型安全自动化字符串。 为 Win 32 平台,BSTR 是长指针指向包含 Unicode 字符串和存储字符串的长度的 32 位整数前缀的分配的内存结构。
因为 Visual Basic 将自动转换所有 Unicode 为为 ASCII 传递外部函数之前,您可以忽略的大多数这一区别。问题,但是,是参数本身中。 默认,Visual Basic 将通过包括字符串引用,传递所有变量。 因为 BSTR 变量是一个指针,指向一个的 String 值值 Visual Basic 将通过引用传递时它实际上为一个字符串指针传递指针。 大多数 C 函数只是需要指向一个字符串,(如 LPSTR) 的一个指针。
创建您的 C DLL: 分步示例
1. 打开 Visual C++5.0 然后在文件菜单上单击新建。 在项目选项卡上选择"Win 32 动态链接库并将该项目命名为"StrSamp"。
2. 再一次在文件菜单上单击新建并选择"与 C++ 源的文件"。 在文件选项卡上命名文件"StrSamp.c,",并按确定。
3. 为文件类型,请重复步骤 2 和此时间选择"文本文件"。 命名文件"StrSamp.def,"并按确定。
4. 接下来,添加以下代码以"StrSamp.c:"
#include <windows.h>
void __stdcall DisplayStringByVal(LPCSTR pszString)
{
//pszString is a pointer to a string
MessageBox(NULL, pszString, "Display String ByVal",
MB_OK | MB_ICONINFORMATION);
}
void __stdcall DisplayStringByRef(LPCSTR* ppszString)
{
//ppszSting is a pointer to a pointer to a string
MessageBox(NULL, *ppszString, "Display String ByRef",
MB_OK | MB_ICONINFORMATION);
}
void __stdcall FillString(LPSTR pszString, LONG cSize)
{
// Create a temp buffer with our string
char buffer[] = "Hello from the C DLL!";
// Copy our temp string to pszString
// but check the size to make sure we have a buffer
// big enough to hold the entire string.
if (cSize > strlen(buffer))
strcpy(pszString, buffer);
}
int __stdcall InStrRev(LPCSTR pszString, short iChar)
{
// This function is similar to Visual Basic's InStr function
// except that it searches for the given ASCII character from
// right to left, returning the character position of the
// last occurrence (rather than the first) of the character
// in the string.
char* pszTmp;
int nRet = 0;
// Scan for iChar in pszString backwards
pszTmp = strrchr(pszString, (int)iChar);
if(pszTmp != NULL)
nRet = pszTmp - pszString + 1;
return nRet;
}
5. 要使这些函数可导出,添加到以下"StrSamp.def:"
LIBRARY StrSamp
DESCRIPTION 'Microsoft KB Sample DLL'
EXPORTS
DisplayStringByVal
DisplayStringByRef
FillString
InStrRev
6. 编译 DLL 从生成菜单。 当完成时,请将新的 DLL 复制到用于测试 Visual Basic 目录中。
在 VB 测试应用程序: 分步示例
1. Visual Basic 中创建一个标准项目并其命名为"StrTest"。 默认情况下会创建 Form 1。
2. 向 Form 1 中添加三个 CommandButtons。
3. 在 Form 1 的代码窗口中将以下添加到 General Declarations 部分:
Option Explicit
Private Declare Sub DisplayStringByRef Lib "StrSamp.dll" _
(sMyString As String)
Private Declare Sub DisplayStringByVal Lib "StrSamp.dll" _
(ByVal sMyString As String)
Private Declare Sub FillString Lib "StrSamp.dll" _
(ByVal sMyString As String, ByVal cBufferSize As Long)
Private Declare Function InStrRev Lib "StrSamp.dll" _
(ByVal sMyString As String, ByVal iChar As Integer) _
As Long
注意字符串的大多数声明 ByVal。 这并不意味着将值传递这些字符串,而不,传递值 (请记住一个 BSTR 变量是字符串指向指针) 在 BSTR 变量的值。 因此 ByVal 关键字将长指针传递给字符串 (LPSTR) 的效果,只是何种 C 函数需要。
4. 将以下代码添加到 Click 事件中,为每个在 CommandButtons:
Private Sub Command1_Click()
Dim sTestString1 As String
Dim sTestString2 As String
sTestString1 = "This is my string passed to the dll by value."
DisplayStringByVal sTestString1
sTestString2 = "This is my string passed to the dll by reference."
DisplayStringByRef sTestString2
End Sub
Private Sub Command2_Click()
Dim sFillTest As String
sFillTest = Space$(260)
FillString sFillTest, 260
MsgBox Trim$(sFillTest), vbInformation, "Fill String"
End Sub
Private Sub Command3_Click()
Dim sPathString As String
Dim sMsg As String
Dim lCharPosition As Long
sPathString = "C:\My Documents\Temp\Item.txt"
lCharPosition = InStrRev(sPathString, Asc("\"))
If CBool(lCharPosition) Then
sMsg = "The file '" & Mid$(sPathString, lCharPosition + 1)
sMsg = sMsg & "' is at this location:" & vbCrLf & vbCrLf
sMsg = sMsg & Left$(sPathString, lCharPosition - 1)
MsgBox sMsg, vbInformation, "InStrRev"
Else
MsgBox "Cannot find '/' in " & sPathString, vbCritical
End If
End Sub
5. 按 F 5 键在 IDE 中运行该 Visual Basic 项目。
注意: 如果您收到错误消息时,可能由于 Visual Basic 找不到您的 DLL。 确保您有复制它到 Visual Basic 目录在运行测试应用程序之前。
用于 Visual Basic 创建 C 的动态链接库 (DLL) 时, 很重要要记住 C 和 Visual Basic 处理字符串方式不同。必须采取每个预防措施以确保正确地传递所有字符串,; 否则,可能会出现一个严重的错误。 这篇文章您展示如何编写函数,在作为参数接受字符串的 C DLL 以及如何从 Visual Basic 应用程序中调用导出的函数。
为了开发 C DLL,很重要,了解如何 Visual Basic 处理字符串在内部以了解如何在将传递给您的 DLL 函数。 大多数 C 函数需要字符串为空终止的 ASCII 字符数组。 但 Visual Basic 使用名为 BSTR 类型安全自动化字符串。 为 Win 32 平台,BSTR 是长指针指向包含 Unicode 字符串和存储字符串的长度的 32 位整数前缀的分配的内存结构。
因为 Visual Basic 将自动转换所有 Unicode 为为 ASCII 传递外部函数之前,您可以忽略的大多数这一区别。问题,但是,是参数本身中。 默认,Visual Basic 将通过包括字符串引用,传递所有变量。 因为 BSTR 变量是一个指针,指向一个的 String 值值 Visual Basic 将通过引用传递时它实际上为一个字符串指针传递指针。 大多数 C 函数只是需要指向一个字符串,(如 LPSTR) 的一个指针。
创建您的 C DLL: 分步示例
1. 打开 Visual C++5.0 然后在文件菜单上单击新建。 在项目选项卡上选择"Win 32 动态链接库并将该项目命名为"StrSamp"。
2. 再一次在文件菜单上单击新建并选择"与 C++ 源的文件"。 在文件选项卡上命名文件"StrSamp.c,",并按确定。
3. 为文件类型,请重复步骤 2 和此时间选择"文本文件"。 命名文件"StrSamp.def,"并按确定。
4. 接下来,添加以下代码以"StrSamp.c:"
#include <windows.h>
void __stdcall DisplayStringByVal(LPCSTR pszString)
{
//pszString is a pointer to a string
MessageBox(NULL, pszString, "Display String ByVal",
MB_OK | MB_ICONINFORMATION);
}
void __stdcall DisplayStringByRef(LPCSTR* ppszString)
{
//ppszSting is a pointer to a pointer to a string
MessageBox(NULL, *ppszString, "Display String ByRef",
MB_OK | MB_ICONINFORMATION);
}
void __stdcall FillString(LPSTR pszString, LONG cSize)
{
// Create a temp buffer with our string
char buffer[] = "Hello from the C DLL!";
// Copy our temp string to pszString
// but check the size to make sure we have a buffer
// big enough to hold the entire string.
if (cSize > strlen(buffer))
strcpy(pszString, buffer);
}
int __stdcall InStrRev(LPCSTR pszString, short iChar)
{
// This function is similar to Visual Basic's InStr function
// except that it searches for the given ASCII character from
// right to left, returning the character position of the
// last occurrence (rather than the first) of the character
// in the string.
char* pszTmp;
int nRet = 0;
// Scan for iChar in pszString backwards
pszTmp = strrchr(pszString, (int)iChar);
if(pszTmp != NULL)
nRet = pszTmp - pszString + 1;
return nRet;
}
5. 要使这些函数可导出,添加到以下"StrSamp.def:"
LIBRARY StrSamp
DESCRIPTION 'Microsoft KB Sample DLL'
EXPORTS
DisplayStringByVal
DisplayStringByRef
FillString
InStrRev
6. 编译 DLL 从生成菜单。 当完成时,请将新的 DLL 复制到用于测试 Visual Basic 目录中。
在 VB 测试应用程序: 分步示例
1. Visual Basic 中创建一个标准项目并其命名为"StrTest"。 默认情况下会创建 Form 1。
2. 向 Form 1 中添加三个 CommandButtons。
3. 在 Form 1 的代码窗口中将以下添加到 General Declarations 部分:
Option Explicit
Private Declare Sub DisplayStringByRef Lib "StrSamp.dll" _
(sMyString As String)
Private Declare Sub DisplayStringByVal Lib "StrSamp.dll" _
(ByVal sMyString As String)
Private Declare Sub FillString Lib "StrSamp.dll" _
(ByVal sMyString As String, ByVal cBufferSize As Long)
Private Declare Function InStrRev Lib "StrSamp.dll" _
(ByVal sMyString As String, ByVal iChar As Integer) _
As Long
注意字符串的大多数声明 ByVal。 这并不意味着将值传递这些字符串,而不,传递值 (请记住一个 BSTR 变量是字符串指向指针) 在 BSTR 变量的值。 因此 ByVal 关键字将长指针传递给字符串 (LPSTR) 的效果,只是何种 C 函数需要。
4. 将以下代码添加到 Click 事件中,为每个在 CommandButtons:
Private Sub Command1_Click()
Dim sTestString1 As String
Dim sTestString2 As String
sTestString1 = "This is my string passed to the dll by value."
DisplayStringByVal sTestString1
sTestString2 = "This is my string passed to the dll by reference."
DisplayStringByRef sTestString2
End Sub
Private Sub Command2_Click()
Dim sFillTest As String
sFillTest = Space$(260)
FillString sFillTest, 260
MsgBox Trim$(sFillTest), vbInformation, "Fill String"
End Sub
Private Sub Command3_Click()
Dim sPathString As String
Dim sMsg As String
Dim lCharPosition As Long
sPathString = "C:\My Documents\Temp\Item.txt"
lCharPosition = InStrRev(sPathString, Asc("\"))
If CBool(lCharPosition) Then
sMsg = "The file '" & Mid$(sPathString, lCharPosition + 1)
sMsg = sMsg & "' is at this location:" & vbCrLf & vbCrLf
sMsg = sMsg & Left$(sPathString, lCharPosition - 1)
MsgBox sMsg, vbInformation, "InStrRev"
Else
MsgBox "Cannot find '/' in " & sPathString, vbCritical
End If
End Sub
5. 按 F 5 键在 IDE 中运行该 Visual Basic 项目。
注意: 如果您收到错误消息时,可能由于 Visual Basic 找不到您的 DLL。 确保您有复制它到 Visual Basic 目录在运行测试应用程序之前。