3
votes

I have a need to create a dll that can be called from PowerBuilder 12.5. I found the RGiesecke.DllExport page at https://sites.google.com/site/robertgiesecke/Home/uploads#TOC-Samples. I created the following very simple c# project as a console app and in the wizard I selected dll:

VS2013 framework 3.5
Windows 7 

using System;
using System.Collections.Generic;
using System.Text;
using RGiesecke.DllExport;
using System.Runtime.InteropServices;

namespace PRS
{
   internal static class UnmanagedExports
   {
     [DllExport("getsmoochie", CallingConvention = CallingConvention.StdCall)]
     static string GetSmoochie()
     {
         return "Success";
     }
   }
}

I compile in Release mode as 32bit then attempt to access the dll from PowerBuilder with:

Function string GetSmoochie() library "PRS.dll"

I get back what looks like Chinese characters.

In addition I find one thing a little strange: if I try to register the dll with Regsvr32 I get and error telling me there is no dll entry point. I don't know what to think of that.

I have additional dll needs for PowerBuilder but I can't seem to get the simplest thing to work. Any help would be appreciated.

Thank you.

UPDATE:

It occurred to me that getting a mangled string back might not be a problem in this case since the code I really need to execute sends a file to a web service so I implemented the SendFile() code and it works from PowerBuilder.

One change I did make from the code above was to add the keyword "public" to the method call.

Summation: the RGiesecke dll Export template works!

UPDATE: See my note below. Here is my call with the filename passed in:

[DllExport("sendfile", CallingConvention = CallingConvention.StdCall)]
public static long SendFile(String filename)

Since the code with the file name hard-coded works I have to assume the file name is getting mangled somehow and the dll can't fin it.

Any ideas?

1
If you run depends.exe and load your built DLL, does it show any exports? It should show AT LEAST your getsmoochie export. - DarinH
Re your question about running Regsvr32, that tool works by calling the DLLRegisterServer entry point in the dll itself. Normal .net dlls don't export that entry point, so Regsvr32 would be useless. Also, usually, Regsvr32 is for registering COM server dlls, so unless you're exporting COM objects, there's no need for a dll to be registered by regsvr32 - DarinH
However, it's possible to create and export that entry point yourself, and then have a regsvr32 registerable .net dll. But first things first :) - DarinH
PowerBuilder 12.5 strings are Unicode. If your DLL uses Ansi strings, that would explain the 'chinese' characters. - Roland Smith
Thanks to everyone trying to help. @DARINH: Depends.exe - In the frame with the "E" in the upper left corner I do see getsmoochie under the FUNCTION column. Also I realize I don't need to register the dll but I wanted to see if I got an error trying to do so. - Howard Taylor

1 Answers

4
votes

You have to marshal your return value too. This code works for me:

[DllExport("ExpTest", CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public static string ExpTest([MarshalAs(UnmanagedType.LPWStr)] string sText, out int length)
{
    MessageBox.Show(sText);
    length=sText.Length;
    return sText;
}

PB 11.5 Classic
Target Framework .NET 4.5.2
Platform target x86