-
Update - Calling a function from a non registering C++ dll
Not wanting to flog a dead horse but I am still having trouble with this.
I have pasted the VB code and the C++ function I am trying to call to see
if anyone can spot an obvious error or something that will help me out.
The call to function TestScript raises the following error in the VB test
code:
"Can't find DLL entry point test_vbscript in C:\Mcam91\Chooks\vbscript.dll"
'==== VB Code
Private Declare Function TestScript Lib "C:\Mcam91\Chooks\vbscript.dll" Alias
"test_vbscript" () As Long
Public Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal
lpLibFileName As String) As Long
Public Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long)
As Long
Public Sub Main()
On Error GoTo PROC_ERR
Dim lngRet As Long
Dim ret As Long
' -- This works fine
lngRet = LoadLibrary("C:\Mcam91\Chooks\vbscript.dll")
If lngRet <> 0 Then
' -- Should call a simple messagebox
Call TestScript '<- Raises an error
If ret = 0 Then ' -- Hard coded 99 on return from function call
MsgBox "Call to TestScript failed ", vbExclamation, "DLL Test"
Else
' Script
End If
Else
MsgBox "Could not load dll 'C:\Mcam91\Chooks\vbscript.dll' ", vbExclamation,
"DLL Test"
End If
PROC_EXIT:
'' -- Clean up
If lngRet <> 0 Then FreeLibrary lngRet
Exit Sub
PROC_ERR:
Err.Source = "modCode::ExecuteScript(Sub)"
MsgBox Err.Description & vbCrLf & vbCrLf & _
"Error Number " & Err.Number & vbCrLf & _
"Error Source " & Err.Source & " ", vbExclamation, "DLL Test"
Resume PROC_EXIT
End Sub
//// C++
/* __________ test_vbscript __________ */
__declspec(dllexport) int __stdcall test_vbscript(void)
{
int iRet = MessageBox (NULL, "Success", "VBScript test", MB_OK);
CString str("AfxMessageBox text");
iRet = AfxMessageBox(str, MB_SETFOREGROUND);
return(99); // for testing
}
Compiling on XP Pro with VB6 and VC6++
Any help would be very much appreciated thank you.
-
Re: Update - Calling a function from a non registering C++ dll
Mick George wrote:
> Compiling on XP Pro with VB6 and VC6++
>
> Any help would be very much appreciated thank you.
Open the DLL with the dependancy viewer that comes with VS (or is on the
internet somewhere if that fails) and see if you can see the function. If
not its a problem with your C++ stuff - maybe a bad .def file for DLL
exports.
--
Max Bolingbroke MCP
http://www.bolingbroke.net/novanet/
-
Re: Update - Calling a function from a non registering C++ dll
1) You don't need to call LoadLibrary in order to use an exported API ...
just call it.
2) Is the path specified for the dll accurate for both the dev and test
systems?
3) have you tried compiling to a different dll name ... I'd be wary of using
the name "vbscript" for obvious reasons.
4) do you have an exports section in the dll?
There is also a KB article which may or may not pertain, and which I confess
contains terminology outside my expertise:
PSS ID Number: Q140485
Article Last Modified on 08-3-2001
--------------------------------------------------------------------------------
The information in this article applies to:
a.. Microsoft Visual C++ 2.0, 2.1, 2.2, 4.0
b.. Microsoft Visual C++, 32-bit Enterprise Edition 5.0, 6.0
c.. Microsoft Visual C++, 32-bit Professional Edition 5.0, 6.0
d.. Microsoft Visual C++, 32-bit Learning Edition 6.0
--------------------------------------------------------------------------------
Summary
There is no _pascal keyword in the 32-bit editions of Visual C++. Instead
the Windef.h header file has PASCAL defined as __stdcall. This creates the
correct style calling convention for the function (the called function
cleans up the stack) but decorates the function name differently. So, when
__declspec(dllexport) is used (in a .dll file, for example), the decorated
name is exported instead of the desired PASCAL style name, which is
undecorated and all uppercase.
More Information
PASCAL name decoration is simply the undecorated symbol name in uppercase
letters. __stdcall name decoration prefixes the symbol name with an
underscore (_) and appends the symbol with an at sign (@) character followed
by the number of bytes in the argument list (the required stack space). So,
the function when declared as:
int __stdcall func (int a, double b) is decorated as:
_func@12 The C calling convention (__cdecl) decorates the name as _func.
Whereas the desired PASCAL style name is FUNC.
To get the decorated name set the Generate Mapfile option in the Linker
General category setting.
Use of __declspec(dllexport) does the following:
a.. If the function is exported with C calling convention (_cdecl), it
strips the leading underscore (_) when the name is exported.
b.. If the function being exported does not use the C calling convention
(for example, __stdcall ), it exports the decorated name.
So to simulate PASCAL name decoration and calling conventions, you must have
the "Called Function stack clean-up" provided by using __stdcall and the
undecorated uppercase name.
Because there is no way to override who does the stack clean up, you must
use __stdcall. To undecorate names with __stdcall, you must specify them by
using aliases in the EXPORTS section of the .def file. This is shown below
for the following function declaration:
int __stdcall MyFunc (int a, double b);
void __stdcall InitCode (void); In the .def file:
EXPORTS
MYFUNC=_MyFunc@12
INITCODE=_InitCode@0 For .dll files to be called by programs written
in the 32-bit versions of Visual Basic (versions 4.0 and above), the alias
technique shown in this article is needed in the .def file. If alias is done
in the Visual Basic program, use of aliasing in the .def file is not
necessary. It can be done on the Visual Basic program by adding an Alias
clause to the Declare statement as shown here:
Declare Function MyFunc Lib "dlllibname" Alias "_MyFunc@12" (...)
As Integer The complete syntax for the Visual Basic Declare statement
follows:
[Public | Private ] Declare Function name Lib
"libname" [Alias "aliasname" ] [([arglist])][As type] References
For more information, query the MSDN compact disc using these keywords:
VB alias DLL
NOTE: A very good discussion (with example code) of calling a C .dll file
from Visual Basic can be found in the file Vb4dll.txt in the Visual Basic
directory. If you can not locate the Vb4dll.txt file, please see the
following article in the Microsoft Knowledge Base:
Q150705 SAMPLE: Using VB4DLL.txt File to Develop .dlls for Visual Basic
--
Randy Birch
MVP Visual Basic
http://www.mvps.org/vbnet/
Please respond only to the newsgroups so all can benefit.
"Mick George" <Mick.George@Mastercam.com> wrote in message
news:3e143f17$1@tnews.web.devx.com...
|
| Not wanting to flog a dead horse but I am still having trouble with this.
| I have pasted the VB code and the C++ function I am trying to call to see
| if anyone can spot an obvious error or something that will help me out.
|
| The call to function TestScript raises the following error in the VB test
| code:
|
| "Can't find DLL entry point test_vbscript in
C:\Mcam91\Chooks\vbscript.dll"
|
| '==== VB Code
| Private Declare Function TestScript Lib "C:\Mcam91\Chooks\vbscript.dll"
Alias
| "test_vbscript" () As Long
| Public Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA"
(ByVal
| lpLibFileName As String) As Long
| Public Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As
Long)
| As Long
|
|
| Public Sub Main()
|
| On Error GoTo PROC_ERR
|
| Dim lngRet As Long
| Dim ret As Long
|
| ' -- This works fine
| lngRet = LoadLibrary("C:\Mcam91\Chooks\vbscript.dll")
|
| If lngRet <> 0 Then
| ' -- Should call a simple messagebox
| Call TestScript '<- Raises an error
| If ret = 0 Then ' -- Hard coded 99 on return from function call
| MsgBox "Call to TestScript failed ", vbExclamation, "DLL Test"
| Else
| ' Script
| End If
|
| Else
|
| MsgBox "Could not load dll 'C:\Mcam91\Chooks\vbscript.dll' ",
vbExclamation,
| "DLL Test"
| End If
|
|
| PROC_EXIT:
| '' -- Clean up
| If lngRet <> 0 Then FreeLibrary lngRet
| Exit Sub
|
| PROC_ERR:
| Err.Source = "modCode::ExecuteScript(Sub)"
| MsgBox Err.Description & vbCrLf & vbCrLf & _
| "Error Number " & Err.Number & vbCrLf & _
| "Error Source " & Err.Source & " ", vbExclamation, "DLL Test"
| Resume PROC_EXIT
| End Sub
|
|
| //// C++
|
| /* __________ test_vbscript __________ */
|
|
| __declspec(dllexport) int __stdcall test_vbscript(void)
| {
| int iRet = MessageBox (NULL, "Success", "VBScript test", MB_OK);
| CString str("AfxMessageBox text");
| iRet = AfxMessageBox(str, MB_SETFOREGROUND);
| return(99); // for testing
| }
|
|
| Compiling on XP Pro with VB6 and VC6++
|
| Any help would be very much appreciated thank you.
|
|
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks