Je tente de charger une simple DLL compilée avec GCC dans cygwin dans une application C# .NET. La DLL ressemble à ceciÉchec étrange lors du chargement d'une DLL C compilée avec GCC dans cygwin dans une application C# .NET
#ifndef __FOO_H
#define __FOO_H
#if _WIN32
#define EXPORT extern "C" __declspec(dllexport)
#else //__GNUC__ >= 4
#define EXPORT extern "C" __attribute__((visibility("default")))
#endif
EXPORT int bar();
#endif // __FOO_H
La barre de fonction() retourne juste 42.
Je compilé et Linked la DLL avec
g++ -shared -o foo.dll foo.cpp
Maintenant, je veux charger cette DLL super simple en Application C# WinForms.
public partial class Form1 : Form
{
[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);
public delegate IntPtr Action2();
unsafe public Form1()
{
InitializeComponent();
IntPtr pcygwin = LoadLibrary("cygwin1.dll");
IntPtr pcyginit = GetProcAddress(pcygwin, "cygwin_dll_init");
Action init = (Action)Marshal.GetDelegateForFunctionPointer(pcyginit, typeof(Action));
init();
}
unsafe private void button1_Click(object sender, EventArgs e)
{
IntPtr foo = LoadLibrary("foo.dll"); // CRASH ... sometimes
IntPtr barProc = GetProcAddress(foo, "bar");
Action2 barAction = (Action2)Marshal.GetDelegateForFunctionPointer(barProc, typeof(Action2));
IntPtr inst = barAction();
}
}
Maintenant, la chose étrange est: parfois cela fonctionne et parfois non. Lorsque cela ne fonctionne pas, il se bloque quand il charge foo.dll. Je l'exécute en mode débogage mais je ne reçois même pas d'exception. Le débogueur s'arrête juste comme si je l'ai arrêté moi-même!
J'ai également essayé de charger foo.dll dans le même cadre de pile où je charge cygwin1.dll. Même chose!
Des indices sur les raisons pour lesquelles cela se produit et sur ce que je peux faire pour le faire fonctionner?
Mise à jour 1: Nous utilisons les dernières Cygwin et Visual Studio 2010.
Mise à jour 2: Une hypothèse est qu'il doit avec le calendrier et la collecte des ordures. Il me semble que le temps entre le chargement de cygwin1.dll et le chargement de foo.dll est important. Plus le temps entre les deux appels LoadLibrary est court, plus il semble probable que cela fonctionne.
Mise à jour 3: Si foo.dll réussit la première fois, il réussit toujours pendant une session. Je peux cliquer sur button1 aussi souvent que je le veux.
Remarque: LoadLibrary ("foo.dll") n'échoue pas simplement pour charger foo.dll. Ce serait bien. Je se bloque et le débogueur cesse de fonctionner. Pas même une exception est levée. ET il ne plante pas toujours. Parfois ça marche!
Nous devons utiliser cygwin. Nous voulons compiler un client Hadoop ZooKeeper sur Windows. L'interface de ZooKeeper C dépend de cygwin dans Windows. –
Et pourquoi ça marche parfois? N'est-ce pas étrange? –
@Fair Dinkum Thinkum: Alors dans votre cas, il sera plus facile d'écrire un EXE au lieu de DLL et de communiquer avec l'EXE en ce qui concerne toutes les méthodes connues (pour recommander une méthode, j'ai besoin de plus d'informations). Il me semble être beaucoup plus facile que d'essayer de résoudre le problème avec l'exigence "4K d'espace de travail au fond de votre pile". – Oleg