Я пытаюсь загрузить простую DLL, скомпилированную с GCC в cygwin, в приложение C # .NET.DLL выглядит следующим образом
#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
Функциональная панель () просто возвращает 42.
Я скомпилировал и связал DLL с помощью
g++ -shared -o foo.dll foo.cpp
Теперь я хочу загрузитьЭта супер простая DLL в 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();
}
}
Теперь странная вещь: иногда это работает, а иногда нет.Когда это не работает, это вылетает при загрузке foo.dll.Я запускаю его в режиме отладки, но я даже не получаю исключения.Отладчик просто останавливается, как будто я сам его остановил!
Я также пытался загрузить foo.dll в тот же самый стек, где я загружаю cygwin1.dll.То же самое!
Любые намеки, почему это происходит, и что я могу сделать, чтобы это работало?
Обновление 1: мы используем последние версии cygwin и Visual Studio 2010.
Обновление2: предположение, что это имеет отношение с синхронизацией и сборкой мусора.Мне кажется, что время между загрузкой cygwin1.dll и загрузкой foo.dll имеет значение.Чем короче время между двумя вызовами LoadLibrary, тем больше вероятность того, что оно сработает.
Обновление 3: если загрузка foo.dll завершается успешно в первый раз, она всегда выполняется во время сеанса.Я могу нажимать на button1 так часто, как хочу.
Примечание: LoadLibrary ("foo.dll") не просто не может загрузить foo.dll.Это было бы хорошо.У меня вылетает и отладчик перестает работать.Даже исключение не выбрасывается. И не всегда сбой.Иногда это работает!