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.
Related
I have a problem with import clr that crashes the .exe of my small program.
Here are the imports I use in my program:
import sys
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from PyQt4.QtGui import QApplication, QMainWindow
from PyQt4.Qt import QGridLayout, QWidget
import clr
executablePath = 'E:\\PythonWS\\MyDll\\'
sys.path.append(executablePath)
clr.AddReference("MyDll")
import MyDll
Basically the program compile fine and I get an executable thanks to cx_freeze, but when I launch it with a log, it crashes when comes import clr
I don't know what to do to make it work, if anyone has an idea?
EDIT:
I added a try-except around the import clr like this:
try:
logger.info('in try')
import clr
executablePath = 'E:\\PythonWS\\MyDll\\'
sys.path.append(executablePath)
clr.AddReference("MyDll")
dllPath = clr.FindAssembly('MyDll')
import MyDll
ts = MyDll.TestSystem('127.0.0.1', '127.0.0.1')
print ts.mainBoard.isConnected()
except Exception as e:
logger.info("Unexpected error: {}".format(e))
But even with the try the appplication crashes... That leads me with 2 options,
either my try except isn't good and then why?
there is a real problem with clr and I need help about it.
EDIT2:
I tried importing other module that are from .pyd thinking it might be that the .exe could not find them but all the import I've tried were done without any problem.
EDIT3:
SO! After looking on other posts, I've seen that there were other ways to import dll: by using ctypes for example.
Problem is: my dll is in C# and apparently the import is not supported very well by ctypes... I got errors like WindowsError: [Error -532462766] Windows Error 0xE0434352 which did not help me much since it seems to be a very general error in windows, but this made me think maybe the thing that makes my program crash when importing clr is the same.. Does anyone know what could the error be related to?
So I am back to using .NET clr, but still no luck
For the record: I have tried both python 32 bits and 64 bits. Here are some more information
#with python 32 bits
platform architecture: ('32bit', 'WindowsPE')
sys.platform: win32
os.name: nt
#with python 64 bits
platform architecture: ('64bit', 'WindowsPE')
sys.platform: win32
os.name: nt
So I eventually made it work:
In the end, pythonNET was installed correctly but it seems the version wasn't the best (not sure if not the latest, or not the right version, or bit), so I deleted every file of pythonNET (that I had copy-pasted here and there to be sure it was seen) and downloaded the .whl (here) of a latest version (which wasn't the one pip was downloading).
And eventually the import clr worked...
I hope this helps some of you :)
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.
I need to change the code of the .NET DLL. I am able to see the code by compilable the DLL with .NET reflector, but I am not able to change the code of the DLL. With .NET Reflector, I decompile the code and saved in to my hard disk, but when i am able to recompile the code its giving errors.
Few code is decompiled in binary format few code is decompiled with c#. Is there any tool to change and recompile the DLL?
Here are the tools I used for trying to decompile the DLL:
ILSpy
DisSharp
Reflector7.1 With the Reflexil plugin
Spices.Net.Suite.5.8
Deploy .NET 1.0.0
devextras.codereflect
dotPeek-1.0.0.2545
intellilock
JustDecompile_BETA_2011.1.728.1
Unfortunately, none of the tools giving perfect source code to recompile the DLL code.
The following code is working:
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\ildasm.exe" original.dll /out=code.asm
echo Here changes to code.asm should be done.
C:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe /dll code.asm
So if the change in code is to be small, it's doable by making the changes in assembly code directly. One can compile and disassemble simple methods to see how the assembly code should look like. Putting additional methods inside the assembly file should not be too hard too.
Of course code analyzis should be done using ilspy-like tools, displaying the source code rather than assembly code.
Tools employed here come from Windows SDK (ildasm) and from .net framework (ilasm).
I've had limited success in recompiling DLLs. A better way of going about it is to using Reflector and the Reflexil plugin. You need to have a bit better knowledge of the IL code that makes up .NET assemblies but Reflexil does a great job of describing the OP codes. I have a little walk through on my blog about how I used to modify the PowerShell Cmdlet Help Editor: http://csharpening.net/?p=348
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)."
I am wondering how I would go about correctly setting up a C++/CLI library that wraps native c++ code that has several dependencies. I have tried both statically and dynamically linking the native library to its dependent libraries with no luck.
The Managed C++/CLI dll builds just fine and can be added as a reference to a C# project. However when I attempt to use any of the defined classes i receive either a BadImageFormatException or FileNotFoundException depending how i linked. I believe I need to specify the dependent libraries in the CLI library so it is loaded in the manifest but I am unsure of the process. Also because i know it will come up, I have verified that all of the libraries involved are built on the x86 architecture.
I figured out the problem and everything is working correctly now. It was a combination of several incorrect things all happening together.
If anyone has the same issue, I resolved it by setting up the following:
1) The Boost libraries that were referenced (specifically boost_thread) needed to be compiled with BOOST_THREAD_USE_DLL preprocessor (other boost libraries may need BOOST_ALL_DYN_LINK to just dynamically link everything). This is apparently a common issue.
2) I verified that all dependencies were in system Path (like R Ubben reiterated)
3) I used the DependencyWalker (depends.exe from sourceforge) to analyze my compiled managed DLL. It turned out that the libpq.lib library being used actually referenced additional DLLs that were not included in the lib folder but in the bin folder. So that need to be added to the Path.
4) Part of my wrapper was using the #include header for lists. This forced my library to link against 2.0 framework dependent libraries. This was not compatible with my 4.0 client targeted C# application. This was only made known by parsing through the Warnings from compiling (previously hidden due to C++ generating too many..foolish i know). However this was resulting in a System.BadImageFormateException being thrown despite everything targeting the same x86 architecture.
Hope that helps anyone else who has the same problem. The BadImageFormateException and FileNotFoundException were entirly too vague and unhelpful.
You should make the C++ dll in release mode and use extern "C" for public static things.
I have gotten that error when the dependent libraries were not in the path. The wrapper library is found because of the reference, but the reference does not also take care of the dependent libraries. Try placing them explicitly where the program is executing.