I want to load some C++ dlls compiled in Cygwin to my C# project (4.7.1 or Standard 2.0), and the first step is to load cygwin1.dll
, of course. But I've stuck at this step. As suggested here I've tried something like:
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32", SetLastError = true)]
static extern IntPtr LoadLibrary(string lpFileName);
static void Main(string[] args)
{
IntPtr pcygwin = LoadLibrary("cygwin1.dll");
IntPtr pcyginit = GetProcAddress(pcygwin, "cygwin_dll_init");
Action init = (Action)Marshal.GetDelegateForFunctionPointer(pcyginit, typeof(Action));
init();// Here the error happens
}
but no luck. The app simply crashes and VS output shows "Access violation" error. It happens at the last line (init();
).
Then I tried the same in simple C++ console app (found at the same page referenced above):
#include <windows.h>
typedef void (*PFN_CYGWIN_DLL_INIT)();
int main()
{
HMODULE h = LoadLibrary(TEXT("cygwin1.dll"));
PFN_CYGWIN_DLL_INIT init = (PFN_CYGWIN_DLL_INIT) GetProcAddress(h,"cygwin_dll_init");
init();
}
And it works great. Then I've decided to create a simple C++ DLL in Visual Studio, which will wrap all cygwin access, and then load this new DLL in my C# project, so I've created something like:
typedef void (*an_action)();
HMODULE h_cygwin;
bool initialize()
{
h_cygwin = LoadLibrary(TEXT("cygwin1.dll"));
if (h_cygwin == nullptr)
return false;
auto cygwin_dll_init = (an_action) GetProcAddress(h_cygwin, "cygwin_dll_init");
if (cygwin_dll_init == nullptr)
return false;
cygwin_dll_init();
return true;
}
I've also created a def file that exports the function and loaded the new dll into my C# project. But again I've got access violation crash when cygwin_dll_init()
is reached. Weird thing is that the same exact C++ dll works great if it's called from another C++ console app. But when called from .NET console app - it crashes.
Another thing that I've tried is to increase stack memory limit (I've read somewhere that it may be the reason...), so I've created the following thread:
var thread = new Thread(Runner, int.MaxValue);// maxStackSize = int.MaxValue
thread.Start();
And I've moved all my code in Runner
method executed by the thread. This time the app doesn't crash, but the thread crashes when cygwin_dll_init()
is reached.
Any suggestions?
Thanks!
UPDATE: I've just tried with C++/CLI wrapper, but no luck. The same access violation error strikes again...
UPDATE 2: I've just discovered that, if I use 32bit version of cygwin1.dll
, and compile my C# project for x86 architecture - everything works! But if I use 64bit version of cygwin1.dll
, and compile my C# project for x64 architecture - I'm getting access violation error. The first thing that came through my mind is that file system redirection somehow confuses cygwin1.dll, but it looks that it isn't the case (I've tried with Wow64DisableWow64FsRedirection
). One step closer, but still don't have the solution...