Call C# dll from within Progress 4GL

asimhg

New Member
Hi there,

I have a C# dll that i want to call from Progress code but I get the following error message :

"Could not find entry point _GetDomain@0."

Here is my Progress code :

DEF VAR vResult AS CHAR NO-UNDO.

RUN GetDomain (OUTPUT vResult).

PROCEDURE GetDomain EXTERNAL "CheckDomain.dll":
DEF RETURN PARAM opDomain AS CHAR NO-UNDO.
END PROCEDURE.



Please advise as to what am I doing wrong?
 

FrancoisL

Member
.Net .dll cannot be called from Progress using the EXTERNAL procedure qualifier.

You can add .Net DLL if you have progress 10.2A but not with previous version.
 

asimhg

New Member
How do I add a .Net dll to Progress 10.1C and how do I then call/use it in a .p file.

Thanks for your help.
 

TomBascom

Curmudgeon
You might find this helpful:

Code:
Tip 49 How can I call code in .Net assemblies from 4GL?
>From Jagdish Pai

Regenerate the .Net assembly with "register for COM Interop" = true in Build
settings. That will generate .tlb (Type library). Now you can use that from
Progress in the same manner as a .dll.

If you don't own the source code to regenerate, you can code a .Net wrapper
around dll and expose the wrapper as type library. This is a good way to get
functionality in Progress that is readily available in .Net.

This is from:

60 OpenEdge Tips in 60 Minutes

by The Progress Community,
John Harlow, BravePoint,
Gus Bjorklund, Progress

Gus & John did this presentation last summer at Virtual Interchange 1 and Gus posted the tips to PEG a week or so ago.
 

asimhg

New Member
I tried the tip but I get the error message that the .tlb file is not a valid Windows image.

Please advise.


Thanks,
 

Miklos

New Member
You must do'it with C++...

Never Work's with C#

Example:

.Net C++:
#include <windows.h>
#include <string.h>
//---------------------------------------------------------------------------
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
return 1;
}
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport) char* DameSaludo(char *idioma)
{
if (strcmp(idioma, "en") == 0) return "Hello";
if (strcmp(idioma, "it") == 0) return "Ciao";
if (strcmp(idioma, "gr") == 0) return "Hallo";
if (strcmp(idioma, "fr") == 0) return "Bonjour";
return "Hola";
}

Progress:

PROCEDURE DameSaludo EXTERNAL "C:\Cdll.dll" CDECL:
DEFINE INPUT-OUTPUT PARAMETER a AS CHARACTER NO-UNDO.
END.


DEFINE VARIABLE a AS CHARACTER INITIAL "HolaMundo".


RUN DameSaludo(INPUT-OUTPUT a).


MESSAGE a
VIEW-AS ALERT-BOX INFO BUTTONS OK.


Regards From México!
 

4GLNewbie

Member
I work on an (as would say Tom) ancient and obsolete version of Progress.

I think you can maintain your dll only if you build an exe or some kind of a wrapper ( in c++ o c ) that you can refer in progress as showed above (or the way you used before, i think it's almost the same). Then this "wrapper" will manage to call your c# dll.. and do as interface with your dll.
 

stephane

New Member
I can't run the Miklos example:

Windows C++, Visual Studio 2022 with Progress

Cpp

#include "pch.h"
#include <windows.h>
#include <string.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//---------------------------------------------------------------------------
/*
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
return 1;
}
*/

//---------------------------------------------------------------------------
extern "C" __declspec(dllexport) int HelloWorld(int hello)
{
return hello * 2;
}

Progress

BLOCK-LEVEL ON ERROR UNDO, THROW.

PROCEDURE HelloWorld EXTERNAL "C:\Users\Steee\source\repos\DllHelloWorld\x64\Release\DllHelloWorld.dll" CDECL:
DEFINE INPUT PARAMETER hello AS SHORT NO-UNDO.
DEFINE OUTPUT PARAMETER rCode AS SHORT NO-UNDO.
END.

DEFINE VARIABLE hello AS INTEGER NO-UNDO.
DEFINE VARIABLE rCode AS INTEGER NO-UNDO.
hello = 3.

RUN HelloWorld(hello, OUTPUT rCode).

MESSAGE STRING(rCode)
VIEW-AS ALERT-BOX INFO BUTTONS OK.

The code compiles without errors and warning but I've got "0" in MESSAGE STRING(rCode), this sould get "6".
 
Top