Using VS2013, I created a Visual C++ CLR class library, made no changes to project settings. Targeted Framework = .NET 4.5.2.
Referenced System.Windows.Forms and added string to 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"); } } The above code works fine when built into a VS2013 C++ Win32 console app (with string and windows.h added to stdafx.h, and no changes to project settings):
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); } } All Foo calls work great and I get the four message prompts.
But when the same code is built into a VS2008 C++ Win32 console app (with string and windows.h added to stdafx.h, and no changes to project settings), the app crashes in between the two Foo2b message prompts, reporting:
Unhandled exception at 0x0f5433be in ConsoleApp1.exe: 0xC0000005: Access violation reading location 0x002d1000.
What did I miss? What is wrong with the ::FooImp2(s); statement?
std::stringis, so this will not work. If you need to it to work, stick with a pure C interface.const char *instead ofstd::string).