1. John Fauss
  2. PowerBuilder
  3. Wednesday, 21 October 2020 03:03 AM UTC

I'm wanting to create a simple C++ DLL in Visual Studio 2017 that contains entry points that are callable by PowerBuilder, but this has proven to be a bigger challenge than I anticipated. I've been able to create a C++ DLL project in VS, create a header for an entry point prototype and cpp source files for dllmain and for the entry point.

I get a successful build in VS and the DLL is created, but PB reports run-time error R00015 when trying to execute the DLL entry point. This entry point takes no arguments and returns void (it's simply an exercise at this point that I'm trying to get working), so the problem is not an argument datatype mismatch. I've also tried variations passing in a simple int/long by value and returning a long or a boolean, all producing the same error.

It would be extremely helpful to have a template that I know works with PB that I can build off of. Does anyone have a small example VS project/solution and C++ source code you are willing to share that I can use as a template?

John

Accepted Answer
Daniel Vivier Accepted Answer Pending Moderation
  1. Thursday, 22 October 2020 17:52 PM UTC
  2. PowerBuilder
  3. # Permalink

I have always stuck to C functions (not C++) for calling from PB because it avoids issues about name mangling etc. Your C functions can call C++ functions.

Tricks that I have found are necessary to get things to work in the C, are to precede the return type with __declspec(dllexport) , and follow it with __stdcall.

So for instance one of my function declarations is:

__declspec(dllexport) char* __stdcall getShareInfo(const char *server, const char *share)

Then in addition, I found that you have to include a module definition file (projectname.def) that gives the names of the functions. Here's an example from one of my libraries (Licensing):

LIBRARY "Licensing"

EXPORTS
encrypt @1
decrypt @2
hash @3
SearchTokenGroupsForSID @4
encryptString @5
decryptString @6
killProcessByName @7
createNewMutex @8
getShareInfo @9
getUNCName @10

When the DLL is compiled, you want to be able to do "dumpbin /exports libraryname.dll", and have it show the exact same function names in its list of functions. If the names are different, some name mangling has gone on that you need to avoid by using the hints above. (Dumpbin is in the Visual Studio command-line tools.)

Comment
  1. John Fauss
  2. Friday, 23 October 2020 01:31 AM UTC
Excellent information, Dan! I have found that you can prevent name mangling by prefacing the function prototype statements with: extern "C" before the "__declspec(dllexport)". I greatly appreciate the tips, especially regarding the .def file contents and use of the dumpbin command-line utility. Very helpful!
  1. Helpful
There are no comments made yet.
Andrew Barnes Accepted Answer Pending Moderation
  1. Thursday, 22 October 2020 17:09 PM UTC
  2. PowerBuilder
  3. # 1

Hi John,

If would like an MFC-less DLL, I have uploaded a very simple DLL.  I use it to do bitwise operations that are extremely slow when coded in PowerScript.  This is about the most basic DLL I have.  The Visual Studio version is 2013, but I am sure it can migrate to any version. 

I have never used Google Drive before, but I think you should be able to download it from here:

https://drive.google.com/file/d/15PMtuJ6aae7dLTBlU-JpuI9p2Mt361PI/view?usp=sharing

 

Andy

Comment
  1. John Fauss
  2. Friday, 23 October 2020 01:23 AM UTC
Thank you, Andy! I have downloaded the Zip file you've provided and will examine the solution and source files. I agree with you that what I am looking for is an MFC-less DLL. Visual Studio appears to only provide templates for C++ (or are at least named as C++) projects, so that's what I have resorted to calling this type of project.
  1. Helpful
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Wednesday, 21 October 2020 06:13 AM UTC
  2. PowerBuilder
  3. # 2

Very easy with an MFC template:

Create a C++ "MFC Dynamic Link Library" project in visual studio and there's your template! 
(choose "Shared DLL" after specifying the solution name and hitting the create / ok button. There's 2 other options, but I just followed the tuto as I'm an absolute noob).

I used this little tutorial to see how it works:
https://www.freevbcode.com/ShowCode.asp?ID=3492

Here's the download link for my VS solution of above example: https://drive.google.com/drive/folders/1dnm42bjujJYKCZ527W5eYixVGKdX9GFD?usp=sharing

The only difference with the tutorial is that the tuto used the name MessageDLL and I chose MFCLibrary for some reason.

 

In Powerbuilder:

External function declaration:

FUNCTION Long Message(long hwnd) LIBRARY "MFCLibrary.DLL"

Call from a button on a window:

long hwnd
hwnd = handle(parent)
message(hwnd)

 

There's no need to do a "regsvr32.exe" on this DLL.

Not sure if it would have to be on the GAC, but it works.

Haven't tested on a "clean" machine yet where I haven't compiled the DLL.

regards

Comment
  1. John Fauss
  2. Wednesday, 21 October 2020 19:56 PM UTC
Thank you, Miguel!

The VS project you supplied via your Google Drive appears to have been created using VS 2019 and I'm using 2017, so while I was able to inspect the source code, I could not build from it due to some libarary incompatibilities. However, I successfully ran the "Message" function in the DLL that you included from my test PB app, so I was able to verify that it did indeed work.

I was not thrilled about the prospect of saddled with the overhead of using MFC, because I wanted a test DLL with source code that was as simple as possible. Instead of using the "MFC Dynamic-Link Library" template in Visual Studio under the Visual C++ / MFC templates, I wanted to use the simplier "Dynamic-Link Library (DLL)" template (or the "Dynamic-Link Library with exports (DLL" template) under the Visual C++ / Windows Desktop templates.

Thanks to the content on the web site for which you provided the URL, I was able to discover the root cause of my difficulties: No export definitions (.def) file in the VS project! Once I created a .def file and populated with the names of the DLL entry points that I wanted to call from PB, the functions in the rebuilt DLL could be accessed from PowerBuilder.

Thank you again for your help! -J
  1. Helpful
  1. Miguel Leeuwe
  2. Wednesday, 21 October 2020 20:01 PM UTC
That's great!

I don't like the overhead of MFC either, but I've tried this several times in the past and the linked website just explained it so simple.

To be honest, as long as I can get away of doing things in with a C# DLL, I'll always prefer that option, now that pb2019 made it so easy to use them, but it was nice to figure out as a solution for "maybe someday".

Glad I could help,

regards
  1. Helpful
  1. Miguel Leeuwe
  2. Wednesday, 21 October 2020 20:02 PM UTC
By the way the version I used was indeed VS2019 (Community edition)
  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.