I'm trying to create a C++/CLI wrapper for some native DLLs. There are seven of these DLLs and more in the future so I need to load them dynamically. They all have the same set of functions. LoadLibrary and GetProcAddress worked great in a native application to load these functions.
Whenever I load a DLL and call Initialize, I get AccessViolationException. Im testing with a C# Console app with platform x86 selected.
UPDATE: Not sure why I got down voted. This question hasn't been answered in any of my google searches. I've searched for half a week before even asking. All questions here about the same thing are using a different method. MSDN says AccessViolations in native interop are the sign of serious programming errors. I don't see what i'm doing wrong. I'm marshalling my strings, and checking for nullptrs before calling. The load functions seem to work. If i put in known bad function names, or a DLL path i know is incorrect it tells me that loading failed. If i put in the correct paths/function names it says everything worked, but then crashes when i try to call it. The function TSInit, for the DLL i'm testing doesnt actually do anything in this particular DLL it however might do some actual work for the other DLLs with the same interface.
Update 2:
I think this question is unanswerable. As I've said, there is several DLLs with the exact same interface. Now, i've found out some of them work, and some don't. I checked all of them with dumpbin to confirm they're all x86 compiled and they are. I'm not sure what is wrong with the DLLs that don't work. In native C++ applications, they all work as expected.
typedef long (WINAPI *TSRINIT)(long lType, HWND hParent, RECT *pRect);
namespace Imagery
{
public ref class Recongizer
{
public:
Recongizer(String^ DllPath) { LoadRecongizer(DllPath); }
~Recongizer() { UnloadLibrary(); }
bool LoadRecongizer(String^ DllPath)
{
HInstance = ::LoadLibrary(msclr::interop::marshal_as<std::wstring>(DllPath).c_str());
if (HInstance == nullptr) return false;
if (!LoadFunctions()) return false;
return true;
}
long Initalize(long lType)
{
if (HInstance == nullptr || TSInit == nullptr) return 0;
return TSInit(0, nullptr, nullptr);
}
private:
void UnloadLibrary()
{
if (HInstance != nullptr) ::FreeLibrary(HInstance);
}
bool LoadFunctions()
{
TSInit = (TSRINIT)::GetProcAddress(HInstance, "TSRInit");
if (TSInit == nullptr)
{
ErrorMessage = "TSRInit could not be loaded.";
return false;
}
return true;
}
property String^ ErrorMessage;
private:
HINSTANCE HInstance{ nullptr };
TSRINIT TSInit{ nullptr };
};
}