Recent

Author Topic: Error when executing code from MinGW DLL  (Read 5254 times)

napard

  • Newbie
  • Posts: 5
Error when executing code from MinGW DLL
« on: August 28, 2018, 03:59:23 pm »
Hi all,

I'm back on experiments with Pascal and C interop. I'm in the process of migrating a relatively large project from C to Pascal and I'm having a strange runtime error when trying to run a Pascal program which loads and executes a DLL compiled with MinGW64, this is the DLL code:

Code: [Select]
#include <stdio.h>

void Test()
{
    printf("Hello\n");
}

compiled with:

Code: [Select]
gcc -g -o libtest.dll -shared test.c

This is prog.lpr:

Code: Pascal  [Select][+][-]
  1. program prog;
  2.  
  3. uses CInterface;
  4.  
  5. begin
  6.   Test;
  7. end.
  8.  

And this is cinterface.pas:

Code: Pascal  [Select][+][-]
  1. {$linklib libtest}
  2.  
  3. unit CInterface;
  4.  
  5. interface
  6.  
  7. procedure Test; cdecl; external;
  8.  
  9. implementation
  10. end.
  11.  

This is the error I get, no matter what I try, it seems to be some kind of error related to C runtime incompatibility:

Code: [Select]
    1 [main] prog 10768 child_copy: cygheap read copy failed, 0x1802FF410..0x18030F0A8, done 0, windows pid 10768, Win32 error 6
    212 [main] prog 10768 G:\Documentos\Syncthing\PROYECTOS\C_C++\prog\lazarus_project\prog.exe: *** fatal error - ccalloc would have returned NULL

Apparently, any call to the libc triggers a runtime error, I've tried this on another Windows installation with latest MinGW64 version available and it's exactly the same error.

Have anyone experienced something similar? Thanks


marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Error when executing code from MinGW DLL
« Reply #1 on: August 28, 2018, 04:05:53 pm »
I'm not sure if  using mingw generated import libs work.

Just let Pascal generate its own import stubs:

procedure Test; cdecl; external 'Test'  name 'libtest.dll';

maybe the  'Test'  after external needs a _ prefix because of  name mangling.

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: Error when executing code from MinGW DLL
« Reply #2 on: August 28, 2018, 04:26:20 pm »
*** fatal error - ccalloc would have returned NULL

I'm just guessing here but, the error you're getting and, the fact that you are using printf, leads me to believe that the problem might be that the C library was not initialized when the program was loaded which often results in C library functions, such as printf, not operating properly.

The way I would find out is by writing a short C program that uses the DLL and trace through the C library initialization then do the same thing with the Pascal program and ensure that the C library is being initialized.  It's likely that the reason for your program is not working is related to printf and the C library initialization (or in your case, not being initialized.)

It's just a guess but, I've run into that problem and, usually the simplest solution is to avoid calling C library functions such as printf.   

If you need printf, you can easily implement it using wsprintf from user32 and WriteFile from kernel32.  It ends up being a lot simpler.  The downside is, wsprintf doesn't support as many format specifications as printf and, the most annoying one is that it doesn't support "%*s".  If you want to specify the width, you have to have the width in the format spec itself, e.g, "%10s", another one which is a inconvenient is that, unlike the C library's printf, wsprintf doesn't support integers larger than 32bit (to format those, ntdll has plenty of useful functions.)

IMO, attempting to use the C library (at least in windows) is more trouble than it worth.

HTH.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

napard

  • Newbie
  • Posts: 5
Re: Error when executing code from MinGW DLL
« Reply #3 on: August 28, 2018, 04:40:39 pm »
Ok let's see, I think the correct syntax is:

Code: Pascal  [Select][+][-]
  1. procedure Test; cdecl; external 'libtest' name 'Test';
  2.  

Which is the same as:

Code: Pascal  [Select][+][-]
  1. Procedure Test; cdecl; external;  
  2. {$LinkLib ’libtest’}
  3.  

gives me exactly the same error, I mean, aren't gcc DLLs compatible with FreePascal? How do you interact with an external lib then?
Also, is FreePascal compatible with MSVC compiler generated DLLs?

Thing is, I have a big C project, it uses SDL2 as a backend, compiles and runs fine in Windows and Linux, my idea is to convert that project into a lib and continue development in Pascal, calling functionality from that lib, I think that won't be possible, but I've been in this scenario earlier with another project and it worked, something is broken around this and I don't know what it is...
« Last Edit: August 28, 2018, 04:56:04 pm by napard »

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: Error when executing code from MinGW DLL
« Reply #4 on: August 28, 2018, 05:05:51 pm »
I mean, aren't gcc DLLs compatible with FreePascal? How do you interact with an external lib then?
Also, is FreePascal compatible with MSVC compiler generated DLLs?
Yes FPC and, many other languages, are definitely "compatible"  with DLLs created using other languages BUT, a DLL created by another language _may_ have initialization (or environment) requirements that FPC or another language is not aware of.  In those cases, the DLL isn't going to work properly unless the calling program sets things up the way the DLL expects them.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: Error when executing code from MinGW DLL
« Reply #5 on: August 28, 2018, 05:06:08 pm »
If you are using either mingw or cygwin you may have noticed the interface unit should use (platform) stdcall in some cases.
Try that first.
Note I have always problems with mingw - that's me, not everyone else - and never with cygwin. Probably cygwin adhere's to cdecl everywhere.

That said: if it is a plain interface you should not have problems otherwise half of the bindings in the standard distribution would fail and we would have noticed that.

Can you provide a FULL but simple example, including WHICH library you are trying to use?
That would make testing life so much more easy.
Bottom line: if your library is correct, if the calling convention is correct, FPC delivers.
Also note that IF you use features of a C lib, you may need to link to it:
printf for example....needs to link in the compete C standard library. (silly if you can use write/writeln)
« Last Edit: August 28, 2018, 05:13:24 pm by Thaddy »
Specialize a type, not a var.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Error when executing code from MinGW DLL
« Reply #6 on: August 28, 2018, 05:23:07 pm »
gives me exactly the same error, I mean, aren't gcc DLLs compatible with FreePascal?

Mingw64 alone comes in 4! incompatible versions (POSIX and native threads, SEH and setjmp exceptions), and then there are msys and cygwin builds.  One binary distribution of FPC can't be compatible with all at the same time. I would expect the native threads SEH version of mingw64 to be the most compatible.

A msvcrt version might even be better.

FPC is compatible with windows dlls. We even try to be compatible to the most common gcc derivatives on windows, the ones to build postgres, mysql clientlibs etc. Those work fine. SDL was always "special", see also below.

But mingw64 dlls can be constructed in many ways, and some might assume the main program also to be mingw compiled (and mingw runtime based). That will of course not work.

(I btw see "cyg" in the errors in your error output. Are you sure there are no mixups?)

Quote
How do you interact with an external lib then?
Also, is FreePascal compatible with MSVC compiler generated DLLs?

Same story.

Quote
Thing is, I have a big C project, it uses SDL2 as a backend, compiles and runs fine in Windows and Linux, my idea is to convert that project into a lib and continue development in Pascal, calling functionality from that lib, I think that won't be possible, but I've been in this scenario earlier with another project and it worked, something is broken around this and I don't know what it is...

We can't help you about that. What I do know is that in general you need to select the mingw/gcc toolchains that are the MOST windows like, and don't try to emulate *nix on Windows. For additional details, maybe it is best to ask on a ming64 list what the error means, and in general what issues SDL has on Windows. That error is not in FPC compiled code or general linking knowledge. It is mingw64 (flavour?) and possibly SDL specific.

I worked with SDL myself in the 2007 timeframe myself, and then it was also a trainwreck. They use every dirty trick in the book, including trying to wrap main() using an owner SDL_MAIN wrapper. That might also have something to do with it. The problem is that way it isn't a library, but a framework.

SDL on-windows itself might also have build options. Doing a custom build and disabling as much as possible of the integration at the expense of having to do some extra calls (SDL_INIT?) could also be a way forward.

As for the difference between external name and the external;  {$linklib:  as said the difference is who creates the so called import lib, which are the tables to load the dll on startup that go into the exe. The file you $linklib is generated by mingw, with the "external name", fpc generates them on the fly (and you shouldn't $linklib)
« Last Edit: August 28, 2018, 05:34:38 pm by marcov »

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: Error when executing code from MinGW DLL
« Reply #7 on: August 28, 2018, 05:25:36 pm »
Marco, unless we have code we can't help. Smart to spot the cyg...
Specialize a type, not a var.

napard

  • Newbie
  • Posts: 5
Re: Error when executing code from MinGW DLL
« Reply #8 on: August 28, 2018, 07:42:16 pm »
Ok, first of all thank you for your help,

Quote
(I btw see "cyg" in the errors in your error output. Are you sure there are no mixups?)

pretty sure there are not, I'm using mingw (64bit version) implementation included by MSYS2 from https://www.msys2.org/, and there are no previous Cygwin nor MinGW installs laying around.

Quote
Mingw64 alone comes in 4! incompatible versions (POSIX and native threads, SEH and setjmp exceptions), and then there are msys and cygwin builds.  One binary distribution of FPC can't be compatible with all at the same time. I would expect the native threads SEH version of mingw64 to be the most compatible.

A msvcrt version might even be better.

I understand there are several variants of mingw64, the problem is how to know which is most likely to be compatible with FPC, could it be any incompatibility from threading model to exception mechanism indeed... FPC installed in the system is 64bit by the way, but I guessed wrong about not having this kind of issues. This is not SDL2 related, that's for sure because I have not even got to that point with the tests.

I'm quite disappointed about this aproach to be extremely difficult, I could use MSVC compiler, no problem with that, except that I couldn't make FPC to load a DLL generated with Visual Studio either, that time a format error (something related the wrong DLL header size) was reported by the compilation process in Lazarus, so I'm really stuck with this  :'(

« Last Edit: August 28, 2018, 07:46:16 pm by napard »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Error when executing code from MinGW DLL
« Reply #9 on: August 29, 2018, 11:09:19 am »

I'm quite disappointed about this aproach to be extremely difficult, I could use MSVC compiler, no problem with that, except that I couldn't make FPC to load a DLL generated with Visual Studio either, that time a format error (something related the wrong DLL header size) was reported by the compilation process in Lazarus, so I'm really stuck with this  :'(

DLL in which Visual Studio language?   Is there a place to get it?   I have a VS setup, so might do some testing.

napard

  • Newbie
  • Posts: 5
Re: Error when executing code from MinGW DLL
« Reply #10 on: August 29, 2018, 02:36:09 pm »
Quote
DLL in which Visual Studio language?

Only raw C/C++, not talking about managed languages, just want to interface with old good C we all know.

 

TinyPortal © 2005-2018