Reputation: 43311
Consider the following solution structure: Windows Store C# application + 2 native libraries PInvokeServer and PInvokeServer1. Native libraries code:
// PInvokeServer1
PINVOKESERVER1_API int TestFunction1(void)
{
return 5;
}
// PInvokeServer
PINVOKESERVER_API int TestFunction(void)
{
return TestFunction1();
}
Both functions are extern C
. PInvokeServer depends on PInvokeServer1 (using linker dependencies). PInvokeServer.dll and PInvokeServer1.dll are added to C# project with build action Content, so they are part of the application package. C# declarations:
const string dllName = @"Native\PInvokeServer.dll";
const string dllName1 = @"Native\PInvokeServer1.dll";
[System.Runtime.InteropServices.DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
public static extern int TestFunction();
[System.Runtime.InteropServices.DllImport(dllName1, CallingConvention = CallingConvention.Cdecl)]
public static extern int TestFunction1();
Case 1, doesn't work (module not found):
TestFunction();
Case 2, works:
TestFunction1();
Case 3, works:
TestFunction1();
TestFunction();
Case 1: When PInvoke tries to load PInvokeServer.dll, it cannot resolve native runtime dependency, PInvokeServer1.dll is not loaded, and I get Module not found exception. Placing PInvokeServer1.dll, for example, to System32 directory doesn't help.
Case 2: PInvoke is able to load PInvokeServer1.dll directly.
Case 3. Once PInvokeServer1.dll is loaded, PInvokeServer.dll can be loaded successfully as well.
Im my real program I have native C library depending on several other libraries. All these libraries are added to C# Store application package. But high-level library cannot be loaded, because PInvoke fails to load dependencies. The only way I can think about is to load low-level libraries using LoadLibrary
PInvoke call, and finally use PInvoke call to high-level library. Is there better way?
Upvotes: 1
Views: 545
Reputation: 612794
In a desktop application you could use AddDllDirectory
or SetDllDirectory
to modify the search path. But in a Windows Store application these functions are not available to you. So I see two options:
LoadLibrary
passing the absolute path to the DLLs to load them into the process. Load PInvokeServer1
before PInvokeServer
. Change your p/invoke declarations to specify just the DLL filename. That is, remove the Native
directory from the p/invoke declaration. By calling LoadLibrary
explicitly, you make sure that the two DLLs are loaded into the process. Then subsequent calls to p/invoke functions will result in the already loaded DLLs being used.Upvotes: 2