I have a small WPF application written in C# using VS2008. For one particular task I would like to use some C++/CLI code (since it requires heavy native interop).
I know I can compile the C++/CLI code as a DLL and then reference this from the C# app, but that seems silly when the code in question is going to be fairly small. I want to build them into the same file. (And without extracting a DLL at runtime.)
Via some command-line-compiler magic (similar to that shown here) I have managed to successfully get this to compile and work when compiling C++ code into a C# DLL, for a different application.
When trying the same thing to compile C++ code into a C# EXE, however, while the compile and link works fine, trying to run the resulting executable results in the following error:
Error while trying to run project: Attempt to load an unverifiable executable with fixups (IAT with more than 2 sections or a TLS section.) (Exception from HRESULT: 0x80131019)
The command lines are basically:
cl /nologo /clr /Zi /MDd /DWIN32 /D_LIB /FUmanaged.dll /c interface.cpp /FoDebug\interface.obj
csc /target:module /addmodule:Debug\interface.obj /r:managed.dll App.cs MainWindow.xaml.cs Debug\MainWindow.xaml.g.cs Properties\AssemblyInfo.cs /out:Debug\Program.netmodule
link /entry:TestApp.App.Main /subsystem:Windows /clrimagetype:ijw /debug /ltcg /manifest /out:Debug\TestApp.exe Debug\App.netmodule Debug\interface.obj
Any ideas where it's going wrong? (managed.dll is a separate C# DLL containing common definitions required by both parts of the code. I'm ok with keeping this separate and it's not really related to the problem at hand, but I've included it for completeness.)
The link command line for the working DLL version is basically the same except that it uses /dll instead of /entry: /subsystem: /clrimagetype:. I've tried removing each of those and only the last seems optional and removing it did not help.
Related
In visual studio when we compile the source code it will generate a byte code then when we build it,create a dll file.I have stuck how the byte code(common intermidiate clanguage) is getting execute by the .net framwork.My understand both CIL and DLL are equal but iam not sure about it.please clarify me boss.
In short, when a .Net language compiler compiles a project, it is turned into either a .Net module, or an assembly. Either of them contain IL (Intermediate Language) code. A .Net module alone is not usable, as it must be included in an assembly. (.Net modules are not commonly used. Most commonly, the dll you get from compiling a project is a one module assembly).
Once you "install" this assembly on a target machine, you have two options:
It can either be installed as is, i.e. the Dll contains IL. Only during execution, a component of .Net runtime, called Jitter will convert it to machine code (native assembly), as the code is executed. The process of converting IL to native machine code is repeated each time the assembly is loaded for execution, for each new process.
It can be converted to machine code during installation, (using tools like ngen). With each execution, machine code is ready to be executed, and hence would provide faster startup / first time execution of methods.
Note: The topic in general is broad, and this is 10,000 ft level overview of the process. There are many details, and up-coming technologies like .Net Native have been left out, to keep this answer simple and most relevant to the way the question has been posed.
In simple words,
C# -> C# compiler (compile time) -> Assembly (DLL/EXE) or .net Module (MSIL form)
Assembly -> JIT compiler (run time) -> machine code (binary form)
For more details,
http://msdn.microsoft.com/en-in/library/ht8ecch6(v=vs.90).aspx
The Common Intermediate Language (CIL) code in the .NET framework is the .DLL and .EXE files that you get once Source Code is compiled by the compiler.
The compilation process, in simple terms, have roughly 3 main code stages:
Source Code (Main input to the compiler)
Assembly code/Byte Code (Intermediate result)
Machine Code/Native Code (Final Output that undergoes actual execution)
.DLL or .EXE files fall under 2nd stage.
.DLL is known as library assemblies and .EXE is known as process assemblies. Both are in CIL form.
A process assembly represents a process that will use classes defined in library assemblies.
This means that CIL and DLL are not exactly "equal" as CIL comes in two forms - .DLL (static/library assembly) and .EXE(executable/process assembly).
So, in reality, the .DLL file or the .EXE files (CIL form) are usually ported to a client computer that has the .NET framework installed (indicating that the CLR which has the JIT Compiler in it, is present on it) where, on the surface level, it seems that once you click the .EXE file, it gets executed, but in reality, the CLR(JIT) converts the .DLL/.EXE once this file is clicked, to machine code which finally gets executed in the backend.
For more details, check:
https://en.wikipedia.org/wiki/Common_Intermediate_Language
https://en.wikipedia.org/wiki/Assembly_%28CLI%29
I have several Unmanaged C++ written lib files which I need to link to Managed C++ dll.
Then I need to invoke functions of this Managed C++ from C# application.
First step is OK - Managed C++ dll is created, I can see with ildasm that it exports functions I need. However when I try to call this function from my C#-written test app it says:
An unhandled exception of type 'System.IO.FileLoadException' occurred in Unknown Module.
A procedure imported by {MyManagedCPP.dll} could not be loaded.
This message goes from VS2010.
I made simple experiment - removed dependencies from all lib files in Managed C++ dll and rebuild it.
With this change it is OK - app starts, I can call functions of Managed C++ dll from C# test app.
Is it not possible by design to call managed c++ functions when dll has static linkage with lib files? Technical restriction? Or there is some workaround?
Thanks
You no doubt have an implicit dependency on a native DLL. It isn't clear from the question what DLL that might be. It could be msvcrxx.dll for example, a runtime support library for native C++ code. Which would be rather bad, you don't want to mix CRT versions. Such a missing DLL otherwise prevents the C++/CLI assembly from getting loaded, producing the FileLoadException.
If you have no idea what that DLL might be then you could use SysInternals' ProcMon utility. The trace will show you the program searching for the DLL and not finding it. If it is msvcrxx.dll then be sure to rebuild the .lib files using the same compiler version you used to build the C++/CLI assembly. If it is something else then make sure you copy that DLL to the build directory.
What should be simple has turned into a convoluted mess of ugliness. So here's the story. I downloaded the awesome Box2D, took out the important c++ files and added an interface for SWIG. I then proceeded to create the Swig wrapper by using a makefile
CC=g++
CFLAGS=-c -Wall -fPIC -I../
LDFLAGS=-shared -o box.dll
SOURCES=<OMITTED>
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=box2d.dll
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
swig:
swig -csharp -c++ -outdir Wrapper Box2D.i
clean:
-rm Collision/*.o
-rm Collision/Shapes/*.o
-rm Common/*.o
-rm Dynamics/*.o
-rm Dynamics/Contacts/*.o
-rm Dynamics/Joints/*.o
-rm Rope/*.o
Pretty normal stuff, and it works fine (After fixing %includes and not #includes in the interface file). So I "make swig" in cygwin, no problems there (had to re-order includes so base classes came first). Then I loaded it up in VS.NET 2012, copying all the wrapper .cs files into the solution and moving the DLL over. This is where it gets nasty.
First time round, I believe it was mixed x86 and x64 that was causing great issue. I could instantly see that this was the problem and was in no way confused by the highly descriptive error message:
System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
In my attempts to fix this, much of the Googling resolved that perhaps the calling convention was the culprate, so I changed the SWIG wrapper cpp file to export the functions into the dll as __cdecl rather than __stdcall, and updated the wrapper appropriately.
Anyway so I eventually fixed the x86/x64 mixing by making a new x86 build profile, and then upon calling any function in the dll, the program just hanged. So I decided to revert back to basics and simply compile with __stdcall, no wrapper mods, and just see if it would work.
It didn't.
Now it complains that it's missing entry points:
{"Unable to find an entry point named 'SWIGRegisterExceptionCallbacks_box2d' in DLL 'box2d'.":""} System.Exception {System.EntryPointNotFoundException}
Upon dumping the exports of the DLL, the functions are correctly mangled according to __stdcall
CSharp_b2_aabbMultiplier_get#0
...
SWIGRegisterStringCallback_box2d#4
SWIGRegisterExceptionCallbacks_box2d#44
etc. etc.
Now the C# wrapper end doesn't seem to find this a problem and goes straight ahead and ignores the mangling
[DllImport("box2d", EntryPoint="SWIGRegisterExceptionArgumentCallbacks_box2d")]
So I tried this out of desperation
[DllImport("box2d", EntryPoint = "SWIGRegisterExceptionCallbacks_box2d", CallingConvention = CallingConvention.StdCall)]
Which was met with the same problem. The solution? Stick the mangled name in.
[DllImport("box2d", EntryPoint="SWIGRegisterExceptionArgumentCallbacks_box2d#44")]
... for all 1392 DllImport attributes. Not a solution.
I've tried compiling DLLs with both minGW and Cygwin, so I doubt that the way the DLLs are compiled is much of an issue.
Does anybody have any idea what I'm doing wrong?
So it turns out that C# cannot into Cygwin or MinGW dlls, so I recompiled with VSC++ and everything went fine.
I have a C# windowed application that needs to make use of a third-party API, which is offered only in C. To solve this problem, I've created three projects within VS2008: two C# projects and an empty C++ project. One C# project is my "Wrapper" project, responsible only for producing managed code that calls the C DLL. The other C# project is the windowed application, which makes use of the Wrapper project; let's call this the GUI project.
Inside the C++ project, I've created several C files (*.c) that utilise the third-party API and export (dllexport) suitable functions. I can successfully compile this project into a DLL and have had no problems in calling these functions from my Wrapper project. In case it's relevant, my Wrapper project uses DllImport attributes to reference these functions.
My C++ project has a post-build event that copies the resulting DLL into the output directory of my GUI C# project so that it's picked up at execution time. This feels a bit grim, but it's the only way I've figured out how to do this. My GUI project has a dependency on my Wrapper project, which has a dependency on the C++ project.
What I'm struggling to do, however, is debug (i.e. step-through) my C project code. I've tried to set a breakpoint within the C code in the hope that it would be caught when my C# code executes the relevant function. Unfortunately, as soon as I run my C# application, the IDE warns me that the C breakpoints will never be executed: "No symbols have been loaded for this document."
Any help with this would be greatly appreciated. Here are some things I've played with, but to no avail:
Ensuring the .pdb file has the same timestamp as the DLL file. This hint was followed after a random Google suggested the "No symbols" error could be caused by this.
I've selected "Enabled unmanaged code debugging" in both my C# project properties.
I've tried setting a breakpoint in my C# call just prior to an invocation of one of the DLL methods and attempted to step into the DLL. This didn't work either, it simply stepped over the function.
You should check in the modules list (Normally found in the Debug menu in Visual Studio) to make sure that:
The module is loaded
It is being loaded from the right place
The symbols have been correctly loaded
If the window lists the module, but indicates that symbols aren't loaded then you can force VS to load symbols by right clicking on the module and selecting "Load symbols". If it can't find them automatically then it will prompt you for a path.
I have a C# application which links to a few c# DLLs which in turn use bindings to call c++ functions in other Dlls.
This all works fine if I compile the c++ Dlls with /MTd but when I use /MDd I get an XMLParseException in my C# app complaining that it can't find any Dlls(it fails to find the first of my Dlls that I use). My best guess is that using this other switch causes it to change the path where it looks for its Dlls, causing it to fail. I used DependencyWalker to have a closer look and the two Dlls it actually fails to find are 'IESHIMS.DLL' and 'WER.DLL'. I can't see my c# Dlls anywhere in the tree in DependecyWalker however. Anyone have any ideas what might be wrong here?
Also, using the non-debug equivalents (/MD and /MT) make no difference. Regardless, I can't use /MT as it causes another bug.
EDIT: I've narrowed the problem down somewhat. When compiled and linked using the VS2010 command prompt, my app works fine, with the VS2008 command prompt it still fails to find the Dll. Does anyone know any differences between these two version of VS which could cause the behaviour I described above?
Thanks in advance,
Are you compiling all the modules against the same run-time libraries? From:
http://msdn.microsoft.com/en-us/library/2kzt1wy3(VS.80).aspx
"All modules passed to a given invocation of the linker must have been compiled with the same run-time library compiler option (/MD, /MT, /LD)."