[.net] how to import .lib files in your C# project(managed C# and unmanaged C/C++)

Started by
32 comments, last by vermilion_wizard 16 years, 10 months ago
hi all i am brand new to C# and am trying to do basic stuff like use 3rd party libraries to include in my project. since there is no #include like in C++ i need to know how to be able to use a .lib file and its associating .dll file. i tried the using keyword like this: using glu32.lib;(as just an example) but it tells me that that the namespace name could not be found even though i include the directory where the file resides in the project properties settings. what do you i need to do and how does the .dll play into all this? if i dont want to put the .dll inside win32 does it need to be in the project directory like in C++ or can it be in the same reference directory as the .lib file? thanks for your input! [Edited by - OpenGL_Guru on June 4, 2007 10:49:03 AM]
heh
Advertisement
Quote:
since there is no #include like in C++ i need to know how to be able to use a .lib file and its associating .dll file.

Nitpick: #include is for textual substitution of other files; it does not have anything to do with linking against .lib files.

To answer your question: you don't.

You can't just take any random .lib file and link against it. In C#, you reference assemblies, which are contained in .dll files. You have to right-click the References folder in the Solution Explorer, choose Add Reference, and browse to the reference you want to add.

Not all .dll files are assemblies; if you want to make use of OpenGL, for example, you'll have to obtain an assembly that is a managed wrapper around the native GL class. The Tao framework is one example.
Quote:Original post by jpetrie
Quote:
since there is no #include like in C++ i need to know how to be able to use a .lib file and its associating .dll file.

Nitpick: #include is for textual substitution of other files; it does not have anything to do with linking against .lib files.

To answer your question: you don't.

You can't just take any random .lib file and link against it. In C#, you reference assemblies, which are contained in .dll files. You have to right-click the References folder in the Solution Explorer, choose Add Reference, and browse to the reference you want to add.

Not all .dll files are assemblies; if you want to make use of OpenGL, for example, you'll have to obtain an assembly that is a managed wrapper around the native GL class. The Tao framework is one example.


well the openGL was a bad example. i am looking to read in shapefiles which is GIS stuff and there is an API that comes with it. when you build it it creates a .lib file and a .dll file. so how in the world do you get the assembly for that or any other .dll? and forgive me for asking but why did MS have to make it THAT difficult to simply use stuff that should be simple?

by the way - i am using .NET 2003. i dont know if that makes a difference.
heh
Quote:
well the openGL was a bad example. i am looking to read in shapefiles which is GIS stuff and there is an API that comes with it. when you build it it creates a .lib file and a .dll file. so how in the world do you get the assembly for that or any other .dll?

You don't. Libraries compiled to native code cannot, unless they are COM components, be accessed by managed code directly. You can use Platform Invoke to access specific functions, or you can write a managed wrapper, or you can find an existing managed wrapper.

Quote:
and forgive me for asking but why did MS have to make it THAT difficult to simply use stuff that should be simple?

Microsoft did no such thing (in fact, they've done an excellent job of making interop to native code very easy); you just think its hard, or should be simple/possible because you don't yet have enough of an understanding of the differences between the two domains you're trying to connect.

What your basically asking is akin to "why can't my square peg fit into this round hole?" C# is a managed language, the code you seem to be compiling is unmanaged code. They don't just play nice by default; effort needs to be put in to make them compatible (typically by using a managed wrapper written in C++/CLI, or by exposing the unmanaged interface via COM, or p/invoke).
Quote:Original post by jpetrie
Quote:
well the openGL was a bad example. i am looking to read in shapefiles which is GIS stuff and there is an API that comes with it. when you build it it creates a .lib file and a .dll file. so how in the world do you get the assembly for that or any other .dll?

You don't. Libraries compiled to native code cannot, unless they are COM components, be accessed by managed code directly. You can use Platform Invoke to access specific functions, or you can write a managed wrapper, or you can find an existing managed wrapper.

Quote:
and forgive me for asking but why did MS have to make it THAT difficult to simply use stuff that should be simple?

Microsoft did no such thing (in fact, they've done an excellent job of making interop to native code very easy); you just think its hard, or should be simple/possible because you don't yet have enough of an understanding of the differences between the two domains you're trying to connect.

What your basically asking is akin to "why can't my square peg fit into this round hole?" C# is a managed language, the code you seem to be compiling is unmanaged code. They don't just play nice by default; effort needs to be put in to make them compatible (typically by using a managed wrapper written in C++/CLI, or by exposing the unmanaged interface via COM, or p/invoke).


would you mind giving a basic example of this?? i keep reading about things like [DllImport("someDLL.dll")] but confused as to where to put it. can you run this in console mode or windows application mode?

heh
the best way is to create C++/Cli library.
In Visual Studio 2005 is extremely easy (I've realised a managed DirectX10 engine with no problem).
Just create managed class in C++ and use lib class.
The only complex part are array and string that required some practice with marshal class.


http://www.notjustcode.it

DirectX tutorial

Quote:Original post by robydx
the best way is to create C++/Cli library.
In Visual Studio 2005 is extremely easy (I've realised a managed DirectX10 engine with no problem).
Just create managed class in C++ and use lib class.
The only complex part are array and string that required some practice with marshal class.


#1 i am using VS 2003, so is creating this library still doable?

#2.if #1 is true are there any tutorials on doing this cos i have no idea how to do it. thanks!

EDIT: i found this tutorial here so i am looking at Solution B. the .dll cannot be changed(3rd party .DLL) so this seems like the viable solution. what do you think? THANKS!

[Edited by - OpenGL_Guru on June 1, 2007 1:37:08 PM]
heh
Just a question for the sake of clarity: is the library written in c or c++?

The two will need different solutions.

If it's c, the solution is simple (as jpetrie said, the .net frameworks ability to work with native libraries is impressive. Not only that, but you need to do this with any non-c language, such as pascal). You use the dllimport attribute you mentioned. I won't go into details, since there's a TON of examples of how to use it (as a quick google search showed me). But basically, you provide the name of the dll, the name of the funtion, what it returns, and what arguments it takes. Basically you're telling the compiler how to use the function. That'd be the job of the header in c++, but you have to do it yourself here.

If it's a c++ library, then it's much more complicated, because you can't directly interact with it. You need to use a utility like swig to create a C dll that wraps the c++ library. You can then interact with the C library using the dllimport attribute.

And as was said, you could also create a wrapper with c++/clr, but this requires vs.net 2005 and knowledge of c++. Unfortunately vs.net 2003 doesn't support c++/clr. It has "managed extensions for c++" which is basically ugly .net functionality hacked onto c++. It's also buggy: for example, virtual functions that return a bool always return false. There's other bugs, but I can't think of them at the moment. Steer clear of it. Either use the swig method or upgrade to vs.net 2005. Also, keep in mind that the swig method is crossplatform, while the c++/clr method will only work in windows.

This inconvenience is one of the few major downsides to using a managed language, and as was said, there's no choice due to the fundamentally different way they work.
Quote:Original post by gharen2
Just a question for the sake of clarity: is the library written in c or c++?

The two will need different solutions.

If it's c, the solution is simple (as jpetrie said, the .net frameworks ability to work with native libraries is impressive. Not only that, but you need to do this with any non-c language, such as pascal). You use the dllimport attribute you mentioned. I won't go into details, since there's a TON of examples of how to use it (as a quick google search showed me). But basically, you provide the name of the dll, the name of the funtion, what it returns, and what arguments it takes. Basically you're telling the compiler how to use the function. That'd be the job of the header in c++, but you have to do it yourself here.

If it's a c++ library, then it's much more complicated, because you can't directly interact with it. You need to use a utility like swig to create a C dll that wraps the c++ library. You can then interact with the C library using the dllimport attribute.

And as was said, you could also create a wrapper with c++/clr, but this requires vs.net 2005 and knowledge of c++. Unfortunately vs.net 2003 doesn't support c++/clr. It has "managed extensions for c++" which is basically ugly .net functionality hacked onto c++. It's also buggy: for example, virtual functions that return a bool always return false. There's other bugs, but I can't think of them at the moment. Steer clear of it. Either use the swig method or upgrade to vs.net 2005. Also, keep in mind that the swig method is crossplatform, while the c++/clr method will only work in windows.

This inconvenience is one of the few major downsides to using a managed language, and as was said, there's no choice due to the fundamentally different way they work.


gharen. YES the Library is indeed C. here is a link the functions available.. which is here

if i use the dllImport feature does that mean i dont need to create anything in VC++ (VC 2003) and just reference the parameters as per the functions/parameter list etc that you mentioned??

i am looking at this particular function for example from that link:

SHPHandle SHPOpen( const char * pszShapeFile, const char * pszAccess );

here is my C# code:
using System;using System.Runtime.InteropServices;namespace shapeFileReader{    class Class1	{        [DllImport("shapefile.dll")]        static extern SHPHandle SHPOpen(const char *pszShapeFile, const char *pszAccess);		static void Main(string[] args)		{         Console.WriteLine("reading shapefile parser");		}	}}


i get the error though when i try to build it:
Quote:
c:\apps\microsoft visual studio .net 2003\vc#\csharpprojects\shapefilereader\class1.cs(9,42): error CS1031: Type expected
c:\apps\microsoft visual studio .net 2003\vc#\csharpprojects\shapefilereader\class1.cs(9,67): error CS0145: A const field requires a value to be provided
c:\apps\microsoft visual studio .net 2003\vc#\csharpprojects\shapefilereader\class1.cs(9,69): error CS1041: Identifier expected, 'const' is a keyword
c:\apps\microsoft visual studio .net 2003\vc#\csharpprojects\shapefilereader\class1.cs(9,92): error CS0145: A const field requires a value to be provided


so for this example what is the compiler really complaining about? i am just telling the compiler what the definition of the function is correct? Thanks for everyones help. when i get this working perhaps i could make a readme on nehe or something if it hasnt been written yet :) anyway look forward to hearing from ya. thanks again.



heh
OK, you are probably going to have to get the header file(s) for your library out and take a look at the types and definitions in them. There are a few problems with your example. First, you should use string types instead of const char *, because that is how C# uses strings. Secondly, SHPHandle definition (I am assuming it is some kind of struct) needs to be rewritten in C#, using the struct identifier. This is how your example should look, keeping in mind the fact that I have no idea what exactly the SHPHandle structure actually looks like:

using System;using System.Runtime.InteropServices;namespace shapeFileReader{    [StructLayout(LayoutKind.Sequential)]    struct SHPHandle    {        // whatever members SHPHandle has go here    }    class Class1    {        [DllImport("shapefile.dll")]        static extern SHPHandle SHPOpen(string pszShapeFile, string pszAccess);	static void Main(string[] args)	{            Console.WriteLine("reading shapefile parser");	}    }}
Mike Popoloski | Journal | SlimDX

This topic is closed to new replies.

Advertisement