1. Aubrey Eichel
  2. PowerBuilder
  3. Thursday, 3 May 2018 22:42 PM UTC

Our PowerBuilder application is 2017 Build 1666 on Windows 7.  We have also tried this in PowerBuilder 12.5.1, unsuccessfully.

We are implementing new functionality that will require us to implement a dll.  We are creating the dll using the minGW version gcc version 6.3.0 (MinGW.org GCC-6.3.0-1) (although we have also tried it in Visual C with the same results) compiler.  When we test the dll using a test C program compiled with the same compiler, everything works fine.  However, when we call it from PowerBuilder we get an error number 15 with the message “Error calling external function test2;Ansi” …

We have created our test based on the “Passing strings” example in the Application Techniques document in the Using External Functions… section.

It appears that we are doing everything as suggested so are wondering if anyone has run into this situation and knows what little (or large embarrassing) thing we’ve missed, either in our PowerBuilder definition or the dll itself.

The dll itself contains two functions.  The first returns a string and has no arguments.  The second function returns a string and has a single string as an argument.  Both functions cause the above error.  We have tried several different datatypes and as long as an argument is defined, we get the same error.

The PowerBuilder Local External Function declarations are (we have also tried it without the Alias):
    FUNCTION string test1 () LIBRARY "testdll.dll" alias for "test1;Ansi"
    FUNCTION string test2 (string InString) LIBRARY "testdll.dll" alias for "test2;Ansi"

The PowerBuilder logic that executes these functions is:
    String          ls_InString      = 'Test Executed Successfully'
    String          ls_Return
    ls_Return     = test1 ()    //  This is successful
    ls_Return     = test2 (ls_InString)    //  This is not

The C code is:
#include
#include
#include "testdll.h"

__stdcall  char* test1(void)
{
            return "Testing 1...";
}

__stdcall  char* test2(char *s)
{
            return "Test 2";
}

Although everything we have read indicates we should use __stdcall, if we remove the __stdcall, or change it to __cdecl, test1 without an argument functions correctly and test2 with the argument returns an error number 42 indicating that the datatypes of the argument are mismatched.

Any suggestions you have will be greatly appreciated.  Thanks in advance for your assistance.

Aubrey

Accepted Answer
Arthur Hefti Accepted Answer Pending Moderation
  1. Friday, 4 May 2018 03:34 AM UTC
  2. PowerBuilder
  3. # Permalink

Most likely it's a problem with the name mangling on exporting the functions as well.

See https://stackoverflow.com/questions/4550294/stdcall-name-mangling-using-extern-c-and-dllexport-vs-module-definitions-msvc#4550410 and https://stackoverflow.com/questions/8063842/mingw32-g-and-stdcall-suffix#9032772

You can use a module definition file:

Library MyCLibrary
Exports
test1
test2

Comment
  1. Aubrey Eichel
  2. Friday, 4 May 2018 19:57 PM UTC
Arthur, thanks very much for your help.  The above link led our C guy down the correct path and we are now able to call our dll.  As I mentioned in my reply to Roland, your help is very much appreciated.

  1. Helpful
There are no comments made yet.
Aubrey Eichel Accepted Answer Pending Moderation
  1. Friday, 4 May 2018 15:10 PM UTC
  2. PowerBuilder
  3. # 1

Thank both very much for your suggestions.I did not write the C functions so will pass these suggestions on to the person who did.  I will let you know how it goes.

Comment
  1. Chris Harmon
  2. Saturday, 19 May 2018 05:24 AM UTC
Also check if the DLL is using Unicode or Ansi strings. You have defined the DLL function to expect Ansi strings. You failure could be because you are passing the wrong string type.



 



Good luck

  1. Helpful
There are no comments made yet.
Roland Smith Accepted Answer Pending Moderation
  1. Friday, 4 May 2018 00:49 AM UTC
  2. PowerBuilder
  3. # 2

Are the functions being exported? You either have to specify __declspec(dllexport) or use a .def file to list the exported functions. PowerBuilder expects _stdcall and I like to use the WINAPI macro.

You could add this:

#define DllExport __declspec( dllexport )

And then define the functions like this:

DLLExport datatype WINAPI functionname ( datatype varname ) {

}

Comment
  1. Aubrey Eichel
  2. Friday, 4 May 2018 19:55 PM UTC
Roland, thanks so much for your suggestion.  Started us down a path and we can now call our dll with no issues.  I know you have heard it before, but you, Arthur, and all of the other folks who continue to help those of us in need are greatly apperciated!

  1. Helpful
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.