Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
加载本机非托管C++;DLL放入托管C#应用程序会导致DLL输出垃圾 我有一个本地的、非托管的C++ DLL(SyMulula.Dll),我必须从托管C应用程序中加载和调用。 DLL利用C++类和动态内存分配(通过新< /COD>操作符)。_C#_C++_Dll_Native_Unmanaged - Fatal编程技术网

加载本机非托管C++;DLL放入托管C#应用程序会导致DLL输出垃圾 我有一个本地的、非托管的C++ DLL(SyMulula.Dll),我必须从托管C应用程序中加载和调用。 DLL利用C++类和动态内存分配(通过新< /COD>操作符)。

加载本机非托管C++;DLL放入托管C#应用程序会导致DLL输出垃圾 我有一个本地的、非托管的C++ DLL(SyMulula.Dll),我必须从托管C应用程序中加载和调用。 DLL利用C++类和动态内存分配(通过新< /COD>操作符)。,c#,c++,dll,native,unmanaged,C#,C++,Dll,Native,Unmanaged,它导出一个名为Init的函数,其定义如下: extern "C" __declspec( dllexport ) int Init( void ) { sym = new CSymulator(); sym->Init(); return 0; } int CSymulator::Init( void ) { int *a = new int; *a = 1; FILE *f = fopen( "tmp.log", "wb" );

它导出一个名为
Init
的函数,其定义如下:

extern "C" __declspec( dllexport ) int Init( void )
{
    sym = new CSymulator();
    sym->Init();
    return 0;
}
int CSymulator::Init( void )
{
    int *a = new int;

    *a = 1;

    FILE *f = fopen( "tmp.log", "wb" );
    fprintf( f, "%i", *a );
    fclose( f );

    delete a;
    return 0;
}
DLL中包含的
CSymulator
类有一个相当简单的构造函数:

CSymulator::CSymulator( void )
{
    memset( mem, 0, sizeof( mem ) );
    memset( &rmr, 0, sizeof( rmr ) );
    md = 0;
    ma = 0;
    tacts = 0;
}
由DLL导出的
Init()
函数调用的
CSymulator::Init()
方法定义如下:

extern "C" __declspec( dllexport ) int Init( void )
{
    sym = new CSymulator();
    sym->Init();
    return 0;
}
int CSymulator::Init( void )
{
    int *a = new int;

    *a = 1;

    FILE *f = fopen( "tmp.log", "wb" );
    fprintf( f, "%i", *a );
    fclose( f );

    delete a;
    return 0;
}
我使用这个代码将本机C++ DLL加载到托管C语言应用程序:

public partial class Form1 : Form
{
    public IntPtr SimHandle;

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr LoadLibrary(string libname);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    private static extern bool FreeLibrary(IntPtr hModule);

    [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
    private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

    delegate int SimInit();

    SimInit DLL_Init;

    public void InicjujDLL()
    {
        IntPtr adres;

        adres = GetProcAddress(SimHandle, "Init");
        DLL_Init = (SimInit)Marshal.GetDelegateForFunctionPointer(adres, typeof(SimInit));

        int rc = DLL_Init();
    }

    private void WczytajDLL()
    {
        String fileName = "D:\\prg\\kompilator\\Debug DLL\\symulator.dll";

        SimHandle = LoadLibrary(fileName);
        if (SimHandle == IntPtr.Zero)
        {
            int errorCode = Marshal.GetLastWin32Error();
            throw new Exception(string.Format("Blad przy wczytywaniu biblioteki ({0})", errorCode));
        }
        else
        {
            InicjujDLL();
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        WczytajDLL();
    }
}
此代码应生成一个名为tmp.log的文件,其中的内容为
1
。但出于某种原因,tmp.log包含垃圾数据(一个随机的32位整数值,而不是1;例如,
2550276

它不是产生垃圾输出的唯一函数。任何试图动态分配内存的DLL函数在这样做之后都无法使用它

这好像是用C++的垃圾回收器清除了本地C++的DLL。


如何防止这种行为?

请稍候:查看下面的参考资料:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int MultiplyByTen(int numberToMultiply);
我没有注意到您的代理没有相同的属性

作为参考,我看不到您如何使用LoadLibrary有任何异常:

我自己用精确的参考做了这件事,没有问题。我建议暂时删除DLL中执行的所有代码,只做一个简单的传递值。现在Init()总是返回0。尝试其他方法,因为您以前已将内存归零,所以返回零可能只是mem zero op.Return 1974或其他方法的副作用

确保启用了“允许不安全代码”,并使用内存查看器查看堆栈(您将获得一个指针,这样您就有了一个起点)。如果你在IL旁边这样做,你可能会发现你的记忆被破坏了


HTH

没有必要乱搞
LoadLibrary
<代码>GetProcAddress。读一下p-Invoke我也试过使用p-Invoke(应该在原始问题中提到)。它会导致完全相同的结果:DLL分配和初始化的类不知何故“忘记”了它们成员的值。不相关的(可能):如何声明
mem
,在
memset之前对它做了什么(mem,0,sizeof(mem));
?@philburbaker
mem
声明为类
CSymulator
的公共成员,如下所示:
无符号短mem[65535]
。到目前为止,它只在构造函数中被触及;在任何其他地方都没有被触及。有趣的是,每当我运行试图访问类的DLL代码时,我也会遇到这些访问冲突错误。
第一次机会异常在0x571020a7(msvcr100d.DLL)在gui.exe中:0xC0000005:访问冲突读取位置0xCCCC。gui.exe中发生了类型为“System.AccessViolationException”的第一次意外异常
调用约定属性似乎已解决该问题。谢谢!您很好,先生。