I have native C++ dlls that I need to use in our group's new C# programs. I wanna create C++/CLI wrappers for native C++ dlls, so as to be able to import and compile them in C#.
What I need to know is how to load the dll file in the wrapper source file at the first place. Exactly the same thing that #using <...> does for MSIL, but for loading native C++ dlls.
And also, how will the objects and namespaces inside the dll become accessible then (synatically)?
EDIT:
I use
class __declspec(dllexport) radar
{
// declarations and definitions
...
};
to export my radar class from my radar.dll, and need to import it in a VC++(CLI) program like this: __declspec(dllimport) public class radar; so as to conduct it's definition into C#, but definitely I can't see radar in C#, because its not defined public in VC++(CLI). Even when I wanna use native dll's objects in VC++ dll's code, like radar pos1(); I get:
error C2512: 'radar' : no appropriate default constructor available
How can do this, having just the radar declaration at hand?
END EDIT.
Thank you!
It is automatic, you don't do this yourself. You specify the native DLL import libraries (.lib) in the linker settings for the C++/CLI project, Additional Dependencies setting. The linker links in a reference to the DLL name into the C++/CLI assembly. As soon as the C# code uses any of the managed types in the C++/CLI assembly, the CLR loads the assembly. Windows notices the native DLL references in the DLL and automatically loads them.
This can only come to a good end if Windows can actually find the native DLLs at runtime. Copy them into the build folder of the EXE project. That's awkward, you can do it with a post-build event or by adding them to the C# project with their Copy to Output Directory property set to true.
Related
I am new to Visual Studio, so if I say something wrong, please point me to the right direction.
I have a large C++ project that consists of shared library of around 20 classes and 7 executables, built by CMake in Linux. Each executable has its own CMake setup that links against the library.
I watched couple of videos on VS, managed to understand how to structure code and dependent libraries and successfully compiled the library statically.
I even managed to setup CMake in Visual studio, but started receiving an error that my .dll file is not Win32 application when I tried to build a project that links to it, so I dropped CMake and built the library by first making empty project and then adding necessary files (I thought it's CMake issue).
Long story short, now I have new setup for my library in VS that builds without issues. However I want my library to be dynamic because it makes ton of sense as 7 different projects depend on it and that's how I did it in Linux.
To my big surprise, even though selecting .dll will build, it cannot be linked to (I started all of this as empty project, not .dll template).
What I just discovered that building .dll library requires a macro that looks like (taken from https://learn.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=msvc-170):
#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif
and before return type of any function in library I need to add the macro as:
MATHLIBRARY_API double some_function();
So if I understand correctly, this macro is "exporting" function names to .dll. Does that then mean that I need to open all 20 header files and wrap every single function in it with the macro?
Note that most header files are class declarations, do I need to wrap every single class method, just the public methods and is there a way to make a whole class "exported"?
It seems quite a cumbersome task just to build a shared library. I realize now this is why cmake failed and kinda begs the question on its cross platform capabilities if this wrapping to make .dll in VS needs to be done like this.
I am considering building my library statically, and in the same solution, add additional projects, and make a reference to the static library.
It kills modularity of the project, but it should work fine.
I have a native c++ dll called native.dll.
I have created a c++/cli project called cliWrapper.dll. In this I have two wrapper classes for some classes in native.dll.
And the compilation for this project works fine.
However, when I try to link cliWrapper.dll with my c++/cli console program, the linker complains that I must compile cliWrapper.dll with the compiler option /clr:safe.
Compiling with such option will generate lots of errors since most of native.dll is not verifiable code.
After googling, I see that linking two .module files requires each is compiled with /clr:safe.
Does that mean it is impossible to make a dll that will allow the user to use the wrapper class to do some stuff? I know I can always put those wrapper classes back into the console project and it will compile without problem but I'm just curious about why Microsoft wants to disable such linking?
I am encountering some issues with one project. I need to use two libraries but one needs to be compiled with the /clr switch as the other cannot be compiled with this switch.
Would there be a way to use at the same time those two libraries in one project? Currently it's compiled with /clr and I got linking errors with the noclr library.
If there is no solution I can still launch the noclr library in batchmode but I'd like to avoid it...
My project is in Managed C++, the library tetgen - which needs /clr - is in native C++ and cannot be compiled without the /clr switch, as I get this error
error C3381: 'tetgenio' : assembly access specifiers are only available in code compiled with a /clr option
The other library triangle is in C. I am on Visual Studio 2008 and the project is compiled in 32 bits.
We could use more details, but using managed C++ you can certainly use a mix of managed and unmanaged code. (Microsoft calls their managed c++ code C++/CLI.)
EDIT:
Ok, your compiler error helped. Apparently you have specified a native class, but using public private, or some other access specifier on the name of the native class. From the MSDN docs:
The following sample generates C3381:
// C3381.cpp
**public** class A { // C3381. Remove public or make the class
managed. };
int main() { }
so get rid of the public keyword, and then try compiling again.
You can have multiple projects in a single solution. Right click on the solution in the eolution explorer and add -> existing/new project. Each library project can be added that way and have their own clr settings.
These days, I use Flex & Bison generated some codes to develop a SQL-parser alike tools, these code can't compiled silently(may be this another topic) in VS2005,but GCC/G++ works well, then I compiled these code with mingw in dll(in windows xp), and then linked these function facades in VS2005, but it seems can't link the dll during linking.
Does MS VS2005 recognize the dll which compiled using mingw on windows? Is there anything I need to do additional? For example, adding something in the include-file that declare the exported APIs?
Does any one can give some advices?
The condition is, as in VS2005, if you want to export some APIs, you may show a *.def file to tell nmake which API you want to export, and then you may create a(or some) *.h file to declare somthing about these APIs(adding some stdcall alike prefix as a call protocal) and some data-type definition. But with GCC/G++, you do not need to do such boring things, just use [ar], you can get these APIs, so my *.h file do not add call protocol and no *.def, just like common function declaration. After *.dll generated, add the *.h file and [mv] generated *.dll in VS2005 project directory, then set the linking *.dll in project setting. Does these steps generated my Question?
BTW, I found and tested VC6-compiled dll can be linked with mingw in Windows XP, but the reverse can't work.
Anyway, forgive my poor English, and thanks for your concern.
VS2005 does not recognize any DLL to compile anything, and I doubt mingw does.
When your application shall use a DLL, you need to tell VS2005 what functions are provided by the DLL.
Load Time Binding
The entry points are defined in the EXPORT directory of the DLL. The content of the EXPORT directory can be defined with the DEF file, while compiling the DLL. Theses exports can also defined using the #pragma __declspec(dllexport) directive. When you compile the DLL the linker will also generate a *.LIB file for the consuming application. This LIB is called import library.
The signatures of the exported functions must be provided by function prototypes, usually in a *.h file.
When you compile your application with load time binding, you include the *.h file in your source code and add the import library to the project settings. (not the *.DLL) When the O/S loads your application, the static code in the import library will load the DLL, read the EXPORT directory and fix all stubs to access the exported functions (and other symbols).
Dynamic Binding
You can omit the import library and load the DLL with your code using LoadLibrayy at the time that's appropriate. You need to define the pointers to the DLL entrypoints by yourself and must intialize theses pointers before calling GetProcAddress the actual functions.
I'm looking at incorporating Lua into a C++ project, and am a bit confused by the presence of the two binaries (lua51.dll and lua5.1.dll) in the distribution from Luabinaries.
According to the docs...
In Windows your library or application
must be linked with a stub library. A
stub library is a library with only
the function declarations that will
bind your DLL with the Lua DLL.
Why? I've never needed stub DLLs before when linking with third-party DLLs?
A stub library is a .lib file, not a DLL. It contains function declarations for all the exported functions in the DLL, which just forward the call into the DLL itself. So if you build an application that you want to link with lua51.dll, you tell the linker to link with lua51.lib, and all calls to exported functions will be forwarded to the DLL. If you didn't do this, you would get a lot of "unresolved external symbol" errors when linking.
This is only needed when statically linking with a DLL (so that it is loaded automatically when the application is run). It is not needed when loading the DLL dynamically with LoadLibrary.
Regarding why they have two different DLLs, The manual says this:
The LuaBinaries DLL packages have a dll proxy called "lua51.dll". It can be used to replace other "lua51.dll" released by other distributions. It will simply forward calls to the "lua5.1.dll". There is no compiled source code involved in the forwarding.
Basically, some existing applications link with lua5.1.dll while others link with lua51.dll and they want to support them both. In any case this is not related to the stub libraries.
I believe it's to do with __declspec(import) and __declspec(export) vs GetProcAddress. However, I don't actually know for sure.