Generate AnyCPU assembly for C# with SWIG - c#

is it possible to create a AnyCpu assembly with SWIG? I have both the x86 and x64 binaries compiled (c++) and I'm able to generate a SWIG P/Invoke Wrapper. But the wrapper is dependent on the invoked native dll (which is CPU specific). But I like the idea of let the executable decide instead of having two different executables. I'm would put the dlls in seperate folders (e.g. named x64/x86) if this is helpful. Or do I have to write a handmade wrapper in C# which decides to load the right dll?
Thanx for input.

It seems you have to roll you own wrapper.
I came across the solution CLRZMQ was using for similar reasons.
They solved it pretty well by embedding both .dll versions and extracting those accoring to the current platform:
They determined the running platform by using Environment.Is64BitProcess and adding a x86 or x64 suffixe + version string before extracting and loading the correct dll.
Here is their solution to the problem and here is the corresponding discussion which gives different ideas on how to solve it. Also interesting is their SafeLibraryHandle which I just found out about.

Related

Could not load file or assembly C++ DLL from a .Net add-in

I have a .Net add-in and within this I have referenced a DLL I have made in C++/CLI. The DLL was designed against the OpenCV API - so now my .Net application can take advantage of the cool graphics capabilities offered by OpenCV.
The problem occurs when I deploy my add-in to other computers. When the user enacts a part of the program that specifically calls upon my C++ DLL it complains about missing the reference:
I suspect the code does not actually know where the DLLs are located but within my dev environment everything (obviously) works as I will have my environment set up different to your standard build PC.
What am I missing here ?
How can I successfully call DLLs created in C++ from a C# add-in? Bearing in mind add-ins are supposed to simplify the customisation of software like Office etc. This is very important - I have to be able to roll in non-.Net DLLs into my project and my code be able to find them.
My dll is just a plain dll, not a COM compatible dll (maybe it should be?) or should I be decorating my C++ code with __declspec(dllexport) a la https://learn.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-declspec-dllexport?view=vs-2017
So 2 things
Use Dependancy Walker to identify any dependancies on your dll and the dlls it uses further down the 'tree' hieracrchy. I found 2 that were missing and it wasn't obvious without this useful tool. Don't be overwhelmed with the results it gives you, just take notice of the missing dlls it's complaining about.
Make sure your dll is referenced within your project and not outside of it in some other folder where you built it.
This fixed my problem - in general just make sure your dlls are on the same path as your executable.

How to combine two managed x86/x64 dlls into one managed AnyCpu library?

A third party compiles unmanaged code (x86/x64 separated) and provides managed C# .NET dlls for either platform (x86/x64 separated):
FooManaged_x86.dll
FooManaged_x64.dll
This is what I receive (neither native code, nor unmanaged dlls).
I can then create a C#.NET application (or library) targetting either x86 or x64 and directly reference the corresponding managed dll - all fine, but restricted to one particular platform (not my goal).
My application can target AnyCpu (my goal), reference the x64 dll (bad, compiler warning), and it will work only when it actually runs as x64. Again, this is bound to one particular platform.
I know, that I can combine unmanaged x86/x64 dlls (with Fody.Costura) into one managed dll by dynamically loading the approriate dll at runtime (using DllImport and manual AssemblyLoad under the hood). I've done this with great success, but this method is not well suited for managed dlls. I would have to PInvoke from managed C# into managed C# dlls - which sounds wrong to me.
Q: Is there any way to combine two managed x86/x64 dlls into one managed AnyCpu dll without PInvoke?
Yes, there is. I've used LibZ successfully to package mixed-mode assemblies as resources into a managed AnyCPU assembly. The library picks the right assembly for the platform it runs on.
It's the technique used in lz4net, by the same author.
The command line in your case would be:
libz inject-dll --assembly YourAnyCpuLib.dll --include FooManaged.x86.dll --include FooManaged.x64.dll
The caveat is that the AnyCPU assembly still has to reference one of the platform-dependent libraries, so you'll get a warning at build time. Just pick the one that you're using for testing/development purposes.
Also, make sure the third party license doesn't forbid you from embedding the assemblies into your own.

How do I Include a .dll in compilation to avoid dynamic linking?

I am using a third party dll file which is referenced within a visual studio project using C#. In previous experiences on other projects, I was able to load objects from different dlls using dllImport, then create objects as if the source code of the dll was included in my project. However, that method is not working with the 3rd part dll. The program works flawlessly on the computer I am programming it on, however, when I run it on a different computer, it cannot find the dll. Is there a method to include the dll compiling and avoid using dynamic linking?
The default setting of .NET Framework is to load native libraries from system paths, not current directory.
But you might learn from System.Data.SQLite project (open source), so as to pre-loading native libraries from current folder, and based on OS bitness,
http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki
Although generating a mixed mode assembly (native and managed bits are merged) sounds like a better solution, System.Data.SQLite users often are confused. Thus, I recommend the pre-loading approach.

Compile some dlls into another dll

I have a dll project which uses some third party dlls. I would like the compilation result to be just one big dll with all the third party dlls included in it. How can I do this in Visual Studio 2010?
You need to use ILMerge, assuming the DLLs are all managed:
http://www.microsoft.com/en-us/download/details.aspx?id=17630
And some related questions:
ILMerge Best Practices
ILMerge question
ILMerge is a .NET only solution (does not work for unmanaged dlls)
A nice tool is NETZ (.net executable compresser and packer) which compresses all your dependencies in a single exe / dll file.
I have not used it recently so I can't tell if it is compatible with .NET 4.0
And it didn't get many updates in a while but I would give it a try.
http://madebits.com/netz/
There are several approaches that you can take here to achieve this. Here are a couple:
You could include the source, if available in one project, and then compile it to a single binary.
You can add the external assemblies as resources, and load them dynamically at runtime.
You can use something like Eazfuscator.Net, which uses ILMerge to merge assemblies at compile time. (can also use ILMerge directly, but Eazfuscator has nice wrapper features) Eazfuscator .Net

Need 64-bit SQLite DLL for managed C# application

I'm trying to embed SQLite into my portable C# .NET 2.0 application rather than having the DLL files included in the distribution folder. However, to embed SQLite, I cannot use the Mixed-Mode libraries provided by PHXSoftware. Instead, I am using their 'Managed Only' version.
This works fine on 32-bit computers, but when it's running on a 64-bit machine, it throws a format exception. As I found out from here: http://sqlite.phxsoftware.com/forums/p/2564/9939.aspx I need to load the unmanaged sqlite3.dll manually in the required architecture format first before I use the managed libraries.
That's where I fall short. I cannot find a 64-bit version of SQLite to include along with the 32-bit one. Can anyone help? Dare I say, does anyone have any better ideas?
I'd recommend you build the source yourself. It's very straight-forward to do. Especially considering Sqlite offers amalgamation source.
Here are the compiler pre-processor defines I use for a 64-bit release build:
WIN64 NDEBUG
_WINDOWS
_USRDLL
NO_TCL
_CRT_SECURE_NO_DEPRECATE
THREADSAFE=1
TEMP_STORE=1
SQLITE_MAX_EXPR_DEPTH=0
Here are the compiler pre-processor defines I use for a 32-bit release build:
WIN32
NDEBUG
_WINDOWS
_USRDLL
NO_TCL
_CRT_SECURE_NO_DEPRECATE
THREADSAFE=1
TEMP_STORE=1
SQLITE_MAX_EXPR_DEPTH=0
The System.Data.SQLite fork has x86/x64 binaries for .Net 2, 3.5, and 4. Downloads are here.
Update:
Another possible solution is to target your application for x86 platform and just use the x86 SQLite libraries. If your application doesn't require x64 features targeting the x86 platform will greatly reduce the complexity of your deployment.

Categories