Question

Using Visual Studio 2008 and Xna 3.1, I've got a piece of hardware 'Mindwave' that has all of its code in a .dll file. I've got a ThinkGear.cs file, which is just a wrapper class that refers to everything in the .dll file with code like:

[DllImport("ThinkGear")]
public static extern int
    TG_GetDriverVersion();

The description given in the comments says this:

This ThinkGear class for C# is simply a thin interface layer which uses InteropServices to provide access to the API functions in the TGCD library, allowing C# programs to use the TGCD to communicate with ThinkGear modules.

When I add the .dll file to the project as a reference I get this error message.

A reference to 'C:\thinkgear.dll' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component.

Does anyone know why a dll might not import or how to get around it? I've tried adding it as content... not sure if thats the right direction.

Was it helpful?

Solution

In .NET, project references must be to assemblies—which in .NET parlance, means managed libraries or executables. The error message you're seeing is a result of the fact that you're trying to add a reference to an unmanaged library, which is not an assembly.

The .NET Framework can make calls into unmanaged libraries using Platform Invocation Services, which is more commonly known by its abbreviated name, P/Invoke. The DllImportAttribute in your wrapper code is part of Platform Invocation Services.

Take a look at the function call you posted:

[DllImport("ThinkGear")]
public static extern int TG_GetDriverVersion();

Note the extern keyword. In C#, extern means that the body of the function is defined somewhere outside of the current assembly. Where outside? That's what the DllImport attribute is for. So this function declaration is saying, "There is a function called TG_GetDriverVersion that takes no parameters and returns an int, but I'm not going to define that function for you; if you want its full definition, go find the unmanaged library 'ThinkGear' and look there."

The compiler doesn't need a reference to resolve this method because you've attached a note to it that says "don't worry about where this actually comes from; I'm telling you what it is, so just use it the way I've declared it and assume that it'll be accessible at runtime."

When you execute your application and you try to invoke TG_GetDriverVersion(), the CLR sees that you've flagged it with extern, checks the DllImport attribute to see which library contains the actual code, searches your hard drive for the library in question (in this case, ThinkGear.dll), loads that library into your process, finds the corresponding function in the library, and invokes it.

As long as the CLR can find the library in question, this should all "just work." So all you need to do is make sure that the correct library exists in your application's bin directory—otherwise, the CLR will throw a runtime exception when it attempts to invoke the function.

OTHER TIPS

[DllImport] is only used for talking to unmanaged (non-COM) dlls. If your DLL is unmanaged, you CANNOT add it as a reference. If your DLL is managed, you do not need the [DllImport] statement.

1) Are you sure that this DLL has unmanaged code it in? If not, you can safely remove the [DllImport] statement

2) If it is unmanaged, you will have to add build step to copy the unmanaged DLL into the bin/debug or bin/release directory. You CANNOT add this dll via a reference! More info about doing this as a post-build step can be found in Copy file(s) from one project to another using post build event...VS2010.

If you are using an unmanaged DLL, I would recommend creating a managed wrapper class around it so you will not have to pollute your entire code base with unsafe calls.

I had the same issue for one of my DLL, though it was a borland c++ DLL and I had no source code about it. I was able to import it in VS and use it by doing those steps :

  1. Register your DLL by using regsvr32
  2. Import the DLL you'll get the normal way you'd do it in Visual Studio : References -> Add Reference -> COM -> your.dll
  3. Now, you should be able to call your functions.

The [DllImport] attribute is what "points" the .cs file at the .dll. You don't need to add any references or register any DLLs or do anything whatsoever except include the .cs files in your project and make sure that the .dll file is in your project's bin folder when you run it. - Cole Campbell

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top