VS2013 构建的 C++/CLI DLL 使用从 VS2008 C++ 应用程序接收的字符串崩溃

VS2013-built C++/CLI DLL crashes using string received from VS2008 C++ app

我使用 VS2013 创建了一个 Visual C++ CLR class 库,没有对项目设置进行任何更改。目标框架 = .NET 4.5.2.

引用 System.Windows.Forms 并将字符串添加到 stdafx.h。

ClassLibrary1.h:

#pragma once

#if defined DO_EXPORT
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif

using namespace System;

extern "C"
{
   DECLDIR void Foo();
   DECLDIR void Foo2a();
   DECLDIR void Foo2b(std::string s);
}

ClassLibary1.cpp:

#define DO_EXPORT
#include "stdafx.h"
#include "ClassLibrary1.h"
using namespace System::Windows::Forms;

void FooImp()
{
}

void FooImp2(std::string s)
{
}

extern "C"
{
    void Foo()
    {
        ::FooImp();
    }

   void Foo2a()
   {
       MessageBox::Show("Entered Foo2a");
       ::FooImp2("");
       MessageBox::Show("Exited Foo2a");
   }

   void Foo2b(std::string s)
   {
       MessageBox::Show("Entered Foo2b");
       ::FooImp2(s);
       MessageBox::Show("Exited Foo2b");
   }
}

以上代码在构建到 VS2013 C++ Win32 控制台应用程序时工作正常(将字符串和 windows.h 添加到 stdafx.h,并且不更改项目设置):

typedef void(*VoidFuncVoid)(void);
typedef void(*VoidFuncStr)(std::string);

int _tmain(int argc, _TCHAR* argv[])

{
   VoidFuncVoid _Foo;
   VoidFuncVoid _Foo2a;
   VoidFuncStr _Foo2b;

   HINSTANCE hInstLibrary1 = LoadLibrary(_T("ClassLibrary1.dll"));

   if (hInstLibrary1)
   {
       _Foo = reinterpret_cast<VoidFuncVoid>(GetProcAddress(hInstLibrary1, "Foo"));
       _Foo();
       _Foo2a = reinterpret_cast<VoidFuncVoid>(GetProcAddress(hInstLibrary1, "Foo2a"));
       _Foo2a();
       _Foo2b = reinterpret_cast<VoidFuncStr>(GetProcAddress(hInstLibrary1, "Foo2b"));
       _Foo2b("");
       FreeLibrary(hInstLibrary1);
   }
}

所有 Foo 调用都很好,我收到了四个消息提示。

但是,当将相同的代码构建到 VS2008 C++ Win32 控制台应用程序时(将字符串和 windows.h 添加到 stdafx.h,并且不更改项目设置),应用程序在两个 Foo2b 消息提示,报告:

Unhandled exception at 0x0f5433be in ConsoleApp1.exe: 0xC0000005: Access violation reading location 0x002d1000.

我错过了什么? ::FooImp2(s); 出了什么问题?声明?

要使用 Visual Studio 内置的库,该库已导出带有标准库参数的 C++ 函数或 类 具有标准库成员,您基本上必须使用相同版本的 Visual Studio为客户。这是因为 Visual Studio 的每个新版本都会对标准库进行更改(因此客户对 std::stringstd::vector 的看法与编译到库中的内容不同)。

如果您需要使用不同版本的 Visual Studio 构建客户端和库,唯一安全的方法是使用严格的 C 接口公开您需要的代码(const char * 而不是 std::stringint ar[], int arCount 而不是 std::vector<int>)。