Results 1 to 14 of 14

Thread: problems with external lib calls

  1. #1

    Thread Starter
    New Member
    Join Date
    Jan 2015
    Posts
    5

    problems with external lib calls

    First problem

    With a c function definition
    //////////////////////////////
    #define VERSION "1.0.0"

    __declspec(dllexport) const char* __stdcall GetVersion()
    {
    return VERSION;
    }
    /////////////////////////////

    why a vb6 declaration like

    Public Declare Function GetVersion Lib "mylib.dll" () As String

    just crash?


    Others functions work fine



    ************************************************************************************

    Second problem


    This same library if i use it from the VB6 IDE it works perfectly ( except for the above function ) but if i build the exe file it crash, i modified the optimizations in the compiler options and after setting the "No optimizations" option the exe file didnt crash, but now it doesnt load ACTIVEXs files which are not registered with regedit, before with just copying the activex in the same folder as the exe file it had worked fine.

    Weirder yet

    i do the dll callings inside a class that is inside another class, but if a do the callings from the parent class it works fine, something like this pseudocode


    Declare LibDoSomething lib .........................


    class class2
    {

    sub DoSomething ()
    call LibDoSomething()
    end sub

    }



    class class1
    {

    sub Something()
    set c2 = new class2
    call c2.DoSomething ''''''''''''''' Crash , in exe file not in IDE
    call LibDoSomething '''''''''' Not crash in exe file nor in IDE
    end sub

    }


    call Something




    somebody has any idea where can be the problem?

    Thanks

  2. #2
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: problems with external lib calls

    Just a wild guess, but VB may be expecting a null terminated string. I don't know C well enough to know if "VERSION" is null terminated in your char* array?
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  3. #3
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: problems with external lib calls

    Quote Originally Posted by edmontreal View Post
    First problem

    With a c function definition
    //////////////////////////////
    #define VERSION "1.0.0"

    __declspec(dllexport) const char* __stdcall GetVersion()
    {
    return VERSION;
    }
    /////////////////////////////

    why a vb6 declaration like

    Public Declare Function GetVersion Lib "mylib.dll" () As String

    just crash?

    A 'const * char' in C is not allowed to be freed on the side of the caller...
    (which IMO is the case with your: Public Declare Function GetVersion Lib "mylib.dll" () As String)

    Better to declare:
    Code:
    Public Declare Function GetVersion Lib "mylib.dll" () As Long)
    ... then followed by copying the Bytes over from the returned (const) Pointer.

    As for your other problems, see if those go away after you fixed the "Version-String-Problem" -
    if these other problems remain persistent - then more info is necessary (which C-Dll or C-Source you are using,
    and what declarations you have on the VB-end).

    Olaf

  4. #4
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: problems with external lib calls

    Quote Originally Posted by Schmidt View Post
    A 'const * char' in C is not allowed to be freed on the side of the caller...

    Olaf
    Olaf, for my own better understanding, I thought that when C (or whatever language) declared a function as StdCall, then caller/callee stack corruption was not an issue any longer? If that's true, then not terminating the string may be the reason for the crash. In either case, I agree that once this is resolved, the other problems probably go away also
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  5. #5
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: problems with external lib calls

    Quote Originally Posted by LaVolpe View Post
    Olaf, for my own better understanding, I thought that when C (or whatever language) declared a function as StdCall, then caller/callee stack corruption was not an issue any longer? If that's true, then not terminating the string may be the reason for the crash. In either case, I agree that once this is resolved, the other problems probably go away also
    The const keyword in C has nothing to do with __stdcall or __cdecl calling-conventions.

    It's more about: "responsibilities with regards to allocations behind pointers".

    C-internally the C-compiler can throw warnings or even compile-errors,
    when a declared "const-char-pointer" (e.g. those pointing to a static allocation,
    as a String-Literal) is either attempted to be overwritten by a strcpy -
    or attempted to be freed or attempted to be re-allocated.

    It's a protection-mechanism for (usually) static allocations (works also for dynamic allocations, but less often used this way).

    In VB we have everything on "full-automatic" - (B)Strings are auto-freed when they
    go out of scope, String-Consts can be passed ByRef into another function,
    overwritten there - but on return will "magically get their old Const-Value".

    In C one needs to take care about such things oneself.

    And declaring something:
    const char *
    instead of only:
    char *

    will help the C-compiler a bit, to identify "issues" and offer a bit more protection -
    and in case of exported functions and parameters, a const-description is telling
    the user on the outside, that it is "not his business to free the allocation behind
    the handed-out string-pointer himself".

    Whereas when StringPointers are returned to the caller which
    are *not* "marked const", it's (usually) the responsibility of the caller who
    received such allocations behind pointers, to free them when he's done.

    The Declaration as it is currently will force VB to make a freeing-attempt
    (unrelated to __stdcall-stack-issues) on the returned static string-pointer-allocation,
    and thus causing a crash.

    In case the VB-Declare for the function shall remain as it currently is in the first posting,
    then the C-function would need to be changed to e.g.:
    Code:
    #define VERSION "1.0.0"
    
    __declspec(dllexport) char* __stdcall GetVersion() //note that we defined char* and not 'const char*'
    {
        char *new_str = malloc(128); //dynamically allocate more than large enough for our-demo purpose
        strcpy(new_str, VERSION );  //copy-over from the static allocation to the dynamic one
        strcat(new_str, "_xyz" );  //just to show how appending another static literal works
        return new_str; //return the dynamic allocation to VBs ANSI-mechanism, which will auto-free it
    }

    The above should work - but there's a small bug (which doesn't exist in VBs ANSI-Automatic
    for ByVal-String-Params) - the call on the VB-Side will not crash, but VB does the wrong
    Len-Calculation in the ANSI-to-W-conversion - and appends the ZeroTerminator-Char as
    part of the String-content, so these returned C-Dll-String-Values are all exactly 1 (W)Char too long.

    So in my own Dll-Bindings I always use Declarations with a Long-(Ptr) return-value at the VB-side -
    and handle the copy-over into a BSTR myself - and depending on const or not const in the
    C-header-declaration, I don't free the pointer afterwards or not - *not* freeing is mandatory
    in case of const return-values - and freeing of "non-const-marked char-return-values" sometimes
    depends, but is usually our responsibility at the VB-end (in case we declared 'As Long').

    When declared 'As String' in the return-value, then VB enforces freeing *always*, no
    matter what (and has the small "off-by-one-char" bug).


    Olaf
    Last edited by Schmidt; Jan 13th, 2015 at 08:21 PM.

  6. #6
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: problems with external lib calls

    The Declaration as it is currently will force VB to make a freeing-attempt (unrelated to __stdcall-stack-issues) on the returned static string-pointer-allocation, and thus causing a crash.
    That part summed it up quite nicely, thank you
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  7. #7
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: problems with external lib calls

    Why not just turn it around and return the result into a provided buffer pointer parameter? Isn't that more typical anyway?

    Then:

    Code:
    Public Declare Sub GetVersion Lib "mylib.dll" (ByVal lpBuffer As String)
    Pad your String out before the call. VB6 assumes ANSI so it implictly handles Unicode/ANSI/Unicode conversion before and after the call.


    The other way you get back a pointer, have to copy the data and convert to Unicode, and then worry about getting the buffer freed back in the DLL by some miracle.

  8. #8
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: problems with external lib calls

    Quote Originally Posted by edmontreal View Post
    ... but now it doesnt load ACTIVEXs files which are not registered with regedit, before with just copying the activex in the same folder as the exe file it had worked fine.
    Just don't do this, it is a leading cause of DLL Hell.

    Use a proper installer, the world will thank you.

  9. #9

    Thread Starter
    New Member
    Join Date
    Jan 2015
    Posts
    5

    Re: problems with external lib calls

    Thanks a lot for the answers related to the first problem. Now, the second problem is not solved because it happens even if i dont call the problematic function, it seems as a matter of the differences between a RELEASE exe and an interpreted execution as well the differences between the optimizations settings, so if somebody knows these details i think i would be able to know where to look for bugs , anyway i'll look for a similar problem in the others functions, just in case, Thanks again and i ll keep you updated.

  10. #10

    Thread Starter
    New Member
    Join Date
    Jan 2015
    Posts
    5

    Re: problems with external lib calls

    Both problems solved guys, the second was a difference between the libraries that the program reads when it was in the modified output folder and in the project folder, MY BAD people, but anyway when the compiler optimizations were removed the release didn't crash that's why i was lost, a very deceiving problem with a very simple cause. Now it works perfectly in debug, RELEASE, optimizations set or not.

    Nevertheless i think that would be good if somebody could explain what exactly does the compiler when optimizations are set and why a program that uses an external library could crash if it use optimizations and run perfectly when not optimizations are set even with the wrong dll.

    Again, thanks a lot. I was a little scared trying to give some new functionality to an old program in a language that i have never touched, but the experience wasn't bad at all, vb6 , 1998 !!!, , not bad at all except for two or three annoying behaviors of the IDE. The community rocks as well

  11. #11
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: problems with external lib calls

    Quote Originally Posted by edmontreal View Post
    Both problems solved guys, the second was a difference between the libraries that the program reads when it was in the modified output folder and in the project folder, ...
    In case you want to ensure the same Std-Dll (or Set of Std-Dlls) to be used in both modes:
    IDE-Debug-Mode and Release/Binary-Mode - you can ensure that per Preloading of the Dll(s)
    in question (per LoadLibrary-WinAPI)

    VB6 App.Path will resolve (in IDE-Mode) to the Directory where your *.vbp is placed in -
    and when running compiled, App.Path resolves to the Directory the compiled Binary in question
    was placed in.

    So, when you have a Project-Root-Folder with a *.vbp in it organized this way:
    \MyProject\
    ... MyProject.vbp
    ... SomeForm.frm
    ... SomeClass.cls
    ... \Release\
    ...... MyProject.exe
    ...... \Bin\
    ......... MyStd.dll
    ......... MyOtherStd.dll

    Then you can preload Dlls explicitely at an early point in your Project-Startup (usually Sub Main()):
    Code:
    Sub Main()
    Dim DllPath As String
      If App.LogMode Then 'we run as a compiled Binary
        DllPath = App.Path & "\Bin\"
      Else 'we run in the IDE
        DllPath = App.Path & "\Release\Bin\"
      End If
    
      LoadLibrary DllPath & "MyStd.dll"
      LoadLibrary DllPath & "MyOtherStd.dll"
    End Sub
    This way you can ensure that you'll always use the same version of Std-Dll(s) -
    no matter if you run in the IDE or from the compiled Binary.


    Quote Originally Posted by edmontreal View Post
    ...but anyway when the compiler optimizations were removed the release didn't crash that's why i was lost, a very deceiving problem with a very simple cause. Now it works perfectly in debug, RELEASE, optimizations set or not.

    Nevertheless i think that would be good if somebody could explain what exactly does the compiler when optimizations are set and why a program that uses an external library could crash if it use optimizations and run perfectly when not optimizations are set even with the wrong dll.
    Not sure which optimizations you mean - the largest difference in compilation-behaviour is,
    when you switch between PCode-compiled Binaries and native-compilation.

    If in native compilation-mode, there's intermediate C-Code generated - which is then compiled
    by the MS-C(++)-Compiler Version 6 (C2.exe in the VB6-Program-Folder) - and here a few
    more Optimizations are available - and if you checked the optimization "No Array-Bounds-Check"
    for example - and your current VB-Code ecpects a 160Bytes-Byte-Array returned from your
    C-Dll - and the older Dll-version delivered for example only a 128Byte long Array - then such
    Crashes are easily explainable.

    Since we don't have all the details of your project we can only speculate - but usually -
    when I discovered discrepancies (no matter which ones) in Error-behaviour between different
    compile-modes or optimization-settings, then it was in almost all cases my fault.

    Quote Originally Posted by edmontreal View Post
    I was a little scared trying to give some new functionality to an old program in a language that i have never touched, but the experience wasn't bad at all, vb6 , 1998 !!!, , not bad at all except for two or three annoying behaviors of the IDE.
    Well, the vbRuntime and certain COMponents were maintained a few years longer than that...

    And yeah - VB6 may serve as a good example, what Devs and Engineers really prefer (and can accomplish)
    with certain APIs and ABIs which remain stable and unbroken over more than just a few years (warts and all)...

    Olaf
    Last edited by Schmidt; Jan 14th, 2015 at 02:28 PM.

  12. #12

    Thread Starter
    New Member
    Join Date
    Jan 2015
    Posts
    5

    Re: problems with external lib calls

    The optimizations that you can set if your option is "Compile to native code" which are "Optimize for fast code"-- default, "Optimize for small code", "No optimization", the question again was why with the option "Optimize for fast code" does not work and with "No optimization" works even with the wrong library version, of course, the problem was not VB , was me, but now im a little curious about these optimizations in the compiler

    thanks again

  13. #13
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: problems with external lib calls

    Quote Originally Posted by edmontreal View Post
    The optimizations that you can set if your option is "Compile to native code" which are "Optimize for fast code"-- default, "Optimize for small code", "No optimization", the question again was why with the option "Optimize for fast code" does not work and with "No optimization" works even with the wrong library version, of course, the problem was not VB , was me, but now im a little curious about these optimizations in the compiler
    Never used the VB5/6 native-Compilation with anything else than "Optimize for fast code" (usually
    accompanied by checking in a few of the additional Compile-Options to speed things up even further).

    When I wanted a small Binary and speed was not really important, then I've always switched
    directly to P-Code Binaries (P-Code compilation and speed is what you have, when running
    a project in IDE-Mode - and if what you experienced there was sufficient, then there's no real
    need to compile to a "fully native" Binary with the underlying C-Compiler).

    That doesn't answer your question though - I perhaps just wanted to give an explanation upfront -
    in case you will receive no satisfying answer here - since I can imagine, that among the native-Compile-
    Options, the experience with: "No optimization" is IMO virtually non-existent among community-members
    (for the reason stated above, that PCode-Binaries are the better "non-optimized" alternative).

    Olaf

  14. #14

    Thread Starter
    New Member
    Join Date
    Jan 2015
    Posts
    5

    Re: problems with external lib calls

    Fair enough, just was curiosity, i was thinking about a irremediable vb6 bug when that was not the case. The lesson is that if something doesnt work with the default settings then something is wrong with you not the compiler ( At least to be humble from the beginning is a good practice even when every compiler is not 100% infallible, by the way, i had some crashes before restoring a wndproc that i actually solved doing tricks, i always blamed vb for that ). Thanks a lot!!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width