vsnprintf和snprintf导致dll无法加载

时间:2019-03-20 16:11:47

标签: c# c .net gcc printf

我已经为此战斗了好几天。我有一个用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,但是它们都具有相同的结果。任何帮助将不胜感激,我已经为此困扰了一段时间。

0 个答案:

没有答案