Clarion MultiDLL application calling function from external DLL - win7 problem

Greetings!

I need to call some functions from one non-clarion DLL (made in Visual Studio 2015). Everything is done like as described in clarionMag article:
https://clarionmag.jira.com/wiki/spaces/clarion/pages/400219/Clarion+and+C+.NET+Interop+without+COM
And I have the same problem as mr. William Cirino mentioned in last comment on that webpage: “in windows 7, in a mult DLL application. the application would always crash”.

Lib file is added to one clarion DLL application and function from external DLL is called from a new procedure. I have a multiDLL clarion application - that new procedure is called from 10-15 other procedures (Clarion exe or dll)… We tested it a lot, and everything is ok on windows 10. But that doesn’t work on windows 7, application always crash - we can’t even start it.

If I move the same lib file / procedure which is calling that external DLL from clarion DLL app to clarion EXE - it works even on windows7. But we really don’t want to have the same procedure in every exe… so… If someone had the same problem and solved that issue - please help.

Regards,
Ognjen Kuzmanovic

I think windows 7 is discontinued.
hth
Nenad

Hi Nenad!
:smile:
We know this, but unfortunately some of our users still use it :persevere:

What version of .net is the non-Clarion assembly dependent on?
Make sure that version of .net framework is installed on the Win7 systems.

Maybe the fact that it works in an EXE vs DLL is a red herring (but still a clue)? Could it have to do with project defines?

non-Clarion assembly depends on .net 4.5 which is installed on the win7 system. I also tried to downgrade .net framework on non-Clarion assembly, no luck.
–> Stopped looking for solution in that direction after realized that my multiDLL app works on win7 if I call the same external DLL directly from EXE.

Do you have something in mind? I tried everything I could think of… (SVDllMode, SVLinkMode …)… But if my project defines isn’t right it also won’t work on windows 10 ?

Yeah, good point. Have you tried running ProcMon while running the app? Perhaps running ProcMon on a system that does NOT crash, then comparing the results to when it does crash?

Hello Ognjen,

from my experience in this topic - the best advice would be to stop using LIB for .NET dll. Instead you should load the dll and get procedure addresses dynamically - using LoadLibrary and GetProcAddress from WinApi.

Best regards,
Andrzej

1 Like

Andrzej,

could you provide some instructions or sample code how to do that? I also use LIB with .NET DLL. Works but I am interested in what you’re suggesting.

Thanks

Bostjan

Hi Bostjan,

you can use LoadLibrary function from WinApi to dynamically load required dll. You can do it at application start or later “on demand” before the first call to any .NET function.

LoadLibrary(*CSTRING pszModuleFileName),UNSIGNED,PASCAL,RAW,NAME('LoadLibraryA')

According to the documentation: “If the function succeeds, the return value is a handle to the module.” You will need that handle to get the addresses of the functions you want to use. You can get them by calling the function GetProcAddress and passing the handle returned from LoadLibrary and the function name as exported from .NET side using eg. [DllExport(“SophisticatedCalculator”)].

GetProcAddress(UNSIGNED hDll, *CSTRING szFuncName),UNSIGNED,PASCAL,RAW

Inside the global MAP in your Clarion application you must prototype your .NET functions, eg.:

MyDotNetCalculation(LONG par1, LONG par2),LONG,PASCAL,RAW,DLL(TRUE)

Name of the function and the names of parameters do not have to be the same as used on the NET side

Next piece of the puzzle - a global LONG variable (maybe ULONG would be better for handling long addresses) that will keep the value returned from the above function GetProcAddress. And now it’s time for the magic part on Clarion’s side :wink: This variable must have a NAME attribute set to the same value as the function name declared in the global map.
myNetFunctionRef LONG,NAME('MyDotNetCalculation')

At this point, after successfully retrieving the function address (myNetFunctionRef = GetProcAddress(handleFromLoadLibrary, funcNameAsExportedFromNet)), you should be able to call anywhere in your app that .NET function like this:
MESSAGE(MyDotNetCalculation(1,2))

Best regards,
Andrzej

2 Likes

Andrzej, do the methods in C# DLL for example still have to be DllExport-ed? Or would this work even without DllExport?

Bostjan

Of course all interop rules and restrictions apply just like with LIBs. A function to be visible for the GetProcAddress must be exported for unmanaged use.

1 Like

It works like a charm!! tnx! :slight_smile: