Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re^2: Import a DLL from C# to Perl

by paulorfmmb (Acolyte)
on May 09, 2018 at 14:04 UTC ( [id://1214279]=note: print w/replies, xml ) Need Help??


in reply to Re: Import a DLL from C# to Perl
in thread Import a DLL from C# to Perl

I called from C like this
#include <windows.h> #include <stdio.h> typedef int (__stdcall *f_funci)(); int initdll(); int main () { if ( initdll() == 1 ) { printf( "Server started!\n" ); } else { printf( "DLL not found\n" ); return 0; } while ( 1 == 1 ) { //printf( "..." ); // preform other dll releted actions } } int initdll() { double a = 1; double b = 2; HINSTANCE hInst = LoadLibrary("C:\\dev\\teste\\DLLExportTest.d +ll"); if( hInst != NULL ) { f_funci funci = (f_funci)GetProcAddress(hInst, "Add"); if (!funci) { printf( "could not locate the function\n" ); return EXIT_FAILURE; } else { funci(&result); } FreeLibrary( hInst ); // temporary return 1; } else { return 0; } }

Replies are listed 'Best First'.
Re^3: Import a DLL from C# to Perl
by syphilis (Archbishop) on May 10, 2018 at 00:25 UTC
    I called from C like this ...

    With your Strawberry Perl, any compilation that is done (eg with Inline::C) will be done using gcc-7.1.0.
    I don't see any issue with your code and gcc-7.1.0.
    And, AFAIK, it doesn't matter whether the dll you want to load was built from C code or C# code or C++ code. Nor should it matter which compiler built it.

    There is the problem that "result" is undeclared - which I "fixed" by commenting out "funci(&result)", as that else block will never be entered in my case, anyway.
    The program then compiled and ran cleanly when built with gcc, outputting "DLL not found" (as expected).

    If that program works fine for you, then it should be fine with Strawberry Perl and Inline::C ... unless, of course, DLLExportTest.dll wants to load a file (eg another dll) that is not locatable in the Srawberry Perl environment.

    This Inline::C script runs fine for me on Strawberry Perl 5.26.0 and, after compilation, outputs "initdll returned: 0".
    use strict; use warnings; use Inline C => Config => BUILD_NOISY => 1; use Inline C => <<'EOC'; typedef int (__stdcall *f_funci)(); int initdll() { double a = 1; double b = 2; HINSTANCE hInst = LoadLibrary("C:\\dev\\teste\\DLLExportTest.dll"); if( hInst != NULL ) { f_funci funci = (f_funci)GetProcAddress(hInst, "Add"); if (!funci) { printf( "could not locate the function\n" ); return EXIT_FAILURE; } else { /* funci(&result); */ } FreeLibrary( hInst ); // temporary return 1; } else { return 0; } } EOC print "initdll returned: ", initdll(), "\n";

    Cheers,
    Rob
      And, AFAIK, it doesn't matter whether the dll you want to load was built from C code or C# code or C++ code.

      There is a problem with C#, in as much as (AFAIK) it always produces .NET Managed Assemblies. Essentially, the DLL contains initialisation and thunking code to connect it to the .NET subsytems, that needs to be called for stuff to work. It's meant to be done by wrapping it in a COM wrapper; but there is another way: Reverse P/Invoke

      At that point, I've described more than I understand, so I'll leave it to the OP to follow the link and read about there.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
      In the absence of evidence, opinion is indistinguishable from prejudice. Suck that fhit
        ... the DLL contains initialisation and thunking code to connect it to the .NET subsytems, that needs to be called for stuff to work

        I can't claim to have any knowledge about C#, but I think that paulorfmmb has indicated that he can access his C#-built dll from C code (presumably using his MS C compiler to build the C executable).
        I was thinking that if the same dll cannot be accessed by an executable built from the same C code, but built with a gcc (mingw-w64) compiler, then it's because of a difference in the environment under which the gcc-built executable is running.
        If that's so, then it's just a matter of fixing the environment when running the gcc-built executable.

        However, I guess it's also possible that building the executable with a Microsoft compiler does stuff that doesn't get done when building with gcc - and that this explains the failure of gcc-built apps to deliver.

        Or, FAIRK, maybe the problem is something entirely different again.

        Cheers,
        Rob
      I still get the same result. Using DEV-C++ I can run the code with no problems, with Inline::C I get the same error.
        Using DEV-C++ I can run the code with no problems, with Inline::C I get the same error

        I think the DEV-C++ success demonstrates that mingw ports of gcc are capable of providing what's needed - since DEV-C++ uses such a port of gcc.

        Inline::C and Inline::CPP provide a Config option (CC => 'C:/other/compiler.exe') that enables the use of a specific compiler. You could try specifying the DEV-C++ compiler as the one to use, and see how that goes.
        Though, for that to work, you might also have to import more of the DEV-C++ environment into the environment under which you're running perl.
        YMMV.

        You could also look at building your own perl with your MSVC compiler. I think (untested by me) that's still a fairly simple procedure:
        1) Download and unpack the perl source.
        2) Open a 'cmd.exe' shell and set up your MSVC environment. (This used to mean running vcvars32.bat ... dunno if that's still appropriate for your case.)
        3) 'cd' to the win32 folder of the perl source.
        4) Configure the "Makefile" file as appropriate. (Just follow the documentation that's in the "Makefile" file.)
        5) Run 'nmake' then 'nmake test' then 'nmake install'.
        6) Always run perl with your MSVC environment set.

        I expect that would deliver what you want - but, as we've already seen, what I expect and what you will get are not necessarily the same.

        Cheers,
        Rob

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1214279]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (3)
As of 2024-04-19 21:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found