我已经为此战斗了好几天。我有一个用C#编写的Visual Studio .net项目,需要在Codeblocks IDE上使用gcc编译器加载用C编写的dll。
可以很好地加载和使用dll,但是当我在dll中使用vsnprintf时,.net项目会显示“无法加载DLL。找不到指定的模块。”每当我尝试从dll调用函数时。
相关的C#代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
namespace Scratchpad
{
public partial class frmMain : Form
{
[DllImport("testpielibs", CallingConvention = CallingConvention.Cdecl)]
static extern void SomeFunction(string a);
private void button3_Click(object sender, EventArgs e)
{
SomeFunction("ABC");
}
}
}
相关的C(DLL)代码:
#include <stdio.h>
#include <stdarg.h>
#define DLL_EXPORT __declspec(dllexport)
void DLL_EXPORT SomeFunction(const LPCSTR sometext)
{
MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);
}
DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
int log_printf(char *format, ...)
{
char msg[256];
va_list ap;
memset(msg, 0, sizeof msg);
va_start(ap, format);
vsnprintf(msg, 256, format, ap);
va_end(ap);
return 0;
}
请注意,“ SomeFunction”甚至没有调用“ log_printf”。无论如何,该项目的构建都很好,当我用vsnprintf注释掉该行时,它就像在.net项目中一样工作,但是那一行是导致dll无法加载到.net项目中的原因。
如果这很轻松,这是我的dll链接程序库:
ws2_32
iphlpapi
mswsock
winmm
user32
此外,我觉得有必要特别注意的是,前几天,就在所有这些事情发生之前,我从代码块中得到了一个错误,提示我的配置文件已损坏。在此之前,该项目的构建情况良好,但我不得不回过头来手动重新分配编译器和链接器设置。
有什么建议吗?
更新:snprintf引起了同样的问题。我可以使用sprintf和vsprintf,但是sndllf和vsnprintf会导致dll无法加载到C#项目中,即使该dll仍会生成且没有错误或警告。我已经研究了用于将dll函数导入到我的C#项目中的调用约定,Cdecl似乎是要走的路,因为它特别说明了它“启用带有varargs的调用函数,这使得它适合用于接受方法的方法可变数量的参数,例如Printf。”我也尝试过使用调用约定Winapi,StdCall和ThisCall导入SomeFunction,但是它们都具有相同的结果。任何帮助将不胜感激,我已经为此困扰了一段时间。