Update - Calling a function from a non registering C++ dll


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 3 of 3

Thread: Update - Calling a function from a non registering C++ dll

  1. #1
    Mick George Guest

    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.



  2. #2
    Max Bolingbroke Guest

    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/


  3. #3
    Randy Birch Guest

    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
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center