Reputation: 16845
I have a C# project which is a library I reference in one of my C# tests I have:
myproj
|-bin
+-External
| |-pHash.dll
|-main.cs
|-MyClass.cs
|-myproj.csproj
pHash.dll
is a Visual C++ library (compiled using a vcproj
project, so we are talking about Microsoft C++ flavor) called phash which exposes this method:
int ph_dct_imagehash(const char* file, ulong64& hash);
I want to use this method from MyClass.cs
. So I do this:
public class MyClass {
[DllImport("pHash.dll")]
static extern int ph_dct_imagehash(
[MarshalAs(UnmanagedType.LPStr)] string file,
[MarshalAs(UnmanagedType.U8)] UInt64 hash);
public MyClass() {...}
public DoStuff() {
UInt64 outputValue = 0;
ph_dct_imagehash("a string", outputValue); // The second parameter should be a pointer in the C++ implementation, not really sure if I am doing it right here
}
}
In my project, I set External/pHash.dll
to be Content
and also set it to be Always copy
in the output folder.
A possible mistake As I pointed out, the way I use ph_dct_imagehash
might be wrong, but this question is about a different error I get, so please skip this and move on :)
MyClass
is then referenced in one of my tests I execute using MSText.exe
.
When I try to run my test which is using that class I get:
System.DllNotFoundException: Unable to load DLL 'pHash.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
What am I doing wrong?
I saw that, when building, actually my bin
folder looks like this:
myproj
+-bin
|-External
|-pHash.dll
So I thought I had to change the path to the DLL:
public class MyClass {
[DllImport("External/pHash.dll")]
static extern int ph_dct_imagehash([MarshalAs(UnmanagedType.LPStr)] string file, [MarshalAs(UnmanagedType.U8)] UInt64 hash);
...
}
But then I get:
System.DllNotFoundException: Unable to load DLL 'External/pHash.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Is there a (maybe debugging?) tool to understand what path is the CLR trying to follow when encountering DllImport
? So at least I know where it is trying to look for that dll...
I have been asked to inspect my dll, so by using DependencyWalker on pHash.dll
, I get this error:
Error: The Side-by-Side configuration information for "c:\myuser\testresults\myuser-0131 2016-05-06 08_56_50\out\PHASH.DLL" contains errors. The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail (14001). Error: At least one required implicit or forwarded dependency was not found. Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module. Error: Modules with different CPU types were found. Warning: At least one delay-load dependency module was not found. Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.
This error is also reported in the stack trace when I run my test. I thought it was a message coming from MSTest
about something else, but now I realize it is a problem of this DLL!
Upvotes: 0
Views: 1405
Reputation: 1004
Even if your DLL is found (sits in the test directory), it is still reported as missing when some of it's dependencies are not found. Make sure you copy the DLL itself and all DLLs it depends on.
Upvotes: 1
Reputation: 7095
You can set select your dll
in Solution Explorer
, right click on it and set BuildAction
to Content
and Copy To Output
directory to CopyAlways
. That way your dll will be copied to application directory and DllImport
should find it.
Alternatively, use DllImport
's SetDllDirectory
with DLL path before first call of your imported dll
[DllImport("kernel32.dll")]
static extern bool SetDllDirectory(string yourPath);
Upvotes: 0