I am porting an application from Windows to Ubuntu written in C#. The application is used to view video from a capture card. I have had to write a C# wrapper for a Dll in windows to access the API for the card, and have written a Wrapper for the corresponding .so in Mono for Ubuntu.
To build and run a C example app for the .so in ubuntu I had to pass "-rdynamic" to gcc to make the application run correctly, else there would be errors such as "Undefined symbol: XMoveWindow". When I try to run my C# app I get "undefined symbol: XvShmCreateImage". I suspect that I need to pass something like "-rdynamic" to the compiler in mono, but I can't find an equivalent command for mono. Is there an equivalent command, and if so what is it?
Thanks in advance
Andrew
This likely means that your .so library is miscompiled (it's not referencing the X11 libs).
You should either recompile this .so lib correctly or you can P/Invoke some function inside libX11 and libXshm before invoking this lib (the functions need not exist, but in that case you need to catch the exceptions, this is needed to load the libraries in the process so that the loader later can find the symbols exported by them).
Related
How do you compile .cs files using C++
I have searched all through Mono's documentation and can't find a way to just compile C# code from the embedded mono runtime in C++. I know how to open a C# .exe assembly file using the embedded mono functions from C++, but I can't seem to find a way to just compile a .cs file to the .exe from C++.
I have also managed to compile the .cs files by calling the mcs.bat file from the CreateProcessA() function that Windows provides, however this does not give me a way to log errors or even check if it succeeded in compilation etc. (It also feels like a hack and not the official solution). The main reason I need to do this is so that I can recompile C# scripts on the fly by detecting when the source code has changed and another subset of conditions.
Does anyone know of a way to properly compile C# files using the embedded Mono runtime? And where to find the documentation for this? Currently I've been using the documentation here: http://docs.go-mono.com/?link=xhtml%3adeploy%2fmono-api-assembly.html which provides enough information for the most part.
Linking Mono in a DLL
Also, if you're familiar with embedding mono, do you know how to use it in a dll? I've managed to successfully link and compile it within a console application, but when I try to compile it as a part of a dynamic library, I get unresolved external symbol errors (specifically functions with the prefix __imp*).
Lastly, I'm using mono to embed C# as a scripting language for my game engine, however I don't know if there is a better (smaller) solution that I can use. If you know of any better solution feel free to leave a recommendation.
The mono runtime is a "Runtime", only for running the code,
but if you have installed the csc command then you can use this:
#include <cstdlib>
int main(){
system("csc yourfile.cs")
return 0;
}
I would like to use C\C++ generated DLLs in LabView, like this example or this one.
I am wondering if it deploys and runs the code on my target machine (my PXIe) or the DLL runs on the computer which is running LabView.
National instruments, in its using external codes in LabView page 15 under Characteristics of the Two Calling Approaches, mention that,
You compile the source code and link it to form executable code. If you
already have a compiled DLL, this step is not necessary.
LabVIEW calls the executable code when the Call Library Function
Node or CIN executes.
LabVIEW passes input data from the block diagram to the executable
code.
LabVIEW returns data from the executable code to the block diagram.
Which I believe it does not clarify whether or not the DLL runs on the target device, aka real-time.
Moreover, I found this document which was quite confusing since it did not refer to any specific method directly.
Side note: I need to run C/C++ code on PXIe and I need to call it from my LabVIEW code real-time.
I have never done this, so I can only try to give a few hints which might help:
If you want to use a dll, it must run on the target where your LabVIEW application runs: If your application runs on a desktop computer, the dll is accessed on the desktop computer. If your application runs on the PXI, the dll must run on the PXI.
Have a look at this NI website:
If the shared library is C++-based, National Instruments strongly
recommends using the MSVC 2009 or MSVC 2010 compilers.
and
If your DLL works on a Windows machine, it may work in LabVIEW
Real-Time (NI PharLap ETS). However, the code will fail if it calls
functions that are not included in the Real-Time operating system's
subset of Win32.
On this website they also have a tool which checks whether a specific dll will work.
I'm developing an Unity app which needs to dynamically load native libraries from outside where the app is installed, for some reason I cannot set the absolute path to DllImport before compiling (such as read the library path in a .txt at runtime and load it), and I don't want to use platform specific API such as LoadLibrary() on Windows or dlopen on Linux because it's inconvenient. And I have been struggled for several days.
I know that the search path can be adjusted by SetDllDirectory() on Windows from this post, and it works well when testing on .NET Framework applications.
However, it does not work in Unity which is based on mono 2.0, it just throws DllNotFoundException at runtime, but it works fine when I use absolute path in DllImport or copy the dll into my Unity project (I'm sure that the code is same)
The next way I tried is environment variable, and it does not work on both .NET and Mono, this post explained that CLR never refreshes the environment during process execution.
The third way I tried is to load the native library with platform specific API such as LoadLibrary() on Windows and dlopen() on Linux first, and then Dllimport may find that the library with same name has already been loaded, then it will use the load library to find function pointers, just as this post did. And I get the same result. The top answer of that question says we can write a wrapper class which uses platform specific API to explicitly load library and get functions pointers, instead of an approach focusing Dllimport, but it is not what I want.
If my guess is right, according to mono's document, DllImportAttribute calls LoadLibrary or dlopen internally at runtime to load a library into memory space. So it follows the search rules of specific OS platform, for example windows:
The directory from which the application loaded.
The current directory
The system directory. Use the GetSystemDirectory() function to get the path of this directory.
The 16-bit system directory.
The Windows directory. Use the GetWindowsDirectory() function to get
the path of this directory.
The directories that are listed in the PATH environment variable.
and Linux:
A colon-separated list of directories in the user’s LD_LIBRARY_PATH
environment variable. This is a frequently-used way to allow native
shared libraries to be found by a CLI program.
The list of libraries cached in /etc/ld.so.cache. /etc/ld.so.cache
is created by editing /etc/ld.so.conf and running ldconfig(8).
Editing /etc/ld.so.conf is the preferred way to search additional
directories, as opposed to using LD_LIBRARY_PATH, as this is more
secure (it’s more difficult to get a trojan library into
/etc/ld.so.cache than it is to insert it into LD_LIBRARY_PATH).
/lib, followed by /usr/lib.
By the way, I also tried to set LD_LIBRARY_PATH at runtime, but it does not work because LD_LIBRARY_PATH will be parsed only once when a process started, which is similar to PATH environment variable on Windows.
So my question is:
Why does the same code performs differently on .NET Framework and Mono? Does Mono just ignore the effect of SetDllDirectory() on Windows? What does DllImportAttribute actually do in Mono?
Is there any way to adjust search path for Unity/Mono apps at runtime, just using DllImport rather than platform specific APIs such as LoadLibrary() and dlopen()?
Unfortunately the answer is that this behaviour is different between Mono on Linux, and .Net on windows, so you are just going to have to deal with that.
The best option, if you know where each DLL is located (e.g. you can put this into a config file), is to load each one explicitly yourself using LoadLibrary or dlopen. This must be done prior to the first call to a DllImport function. DllImport then need not specify a path.
This way you know exactly which DLL you are getting, and can load them in whatever order is correct, if this is an issue.
If for some reason you really don't want to do that, I suggest you create a function like MySetDllDirectory which on Windows calls SetDllDirectory and on Linux sets LD_LIBRARY_PATH. In this way the changes can be isolated to a single module.
I am attempting to make an iSpy plugin using opencv in order to process the image data.
iSpy is written in C#.NET and so must be their plugins, therefore I need a wrapper for OpenCV(which is written in C++). I tried using EMGUCV and OpenCVSharp; emgu based plugin didn't even run as a plugin(also it's very outdated) and ocvsharp has some big performance issues I can't bare for this project.
Since using C# wrappers wasn't an option anymore, I started making an unmanaged C++ project that implements the functionality I need for the plugin and built it as an x64 dll and tried to make a wrapper for this methods and functions to C# in order to use it on the plugin. So far, so good, the wrap works just fine when outside iSpy.
When I try to run the plugin that incorporates this projects via iSpy I get:
System.BadImageFormatException was unhandled by user code
HResult=-2147024885
Message=An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
Source=ImageProcessing
StackTrace:
at ImageProcessing.WrappingMiddleman.Pootis()
at ImageProcessing.ObjectsFinder..ctor(String path, FinderTypes finderType) in c:\Users\Matias Lopez\Documents\GitHub\CCAddons-Testing\FaceSurveillance\ImageProcessing\ObjectsFinder.cs:line 63
at CCAddons.Main.InitConfig() in c:\Users\Matias Lopez\Documents\GitHub\CCAddons-Testing\FaceSurveillance\FaceSurveillance\Main.cs:line 162
at CCAddons.Main.set_Configuration(String value) in c:\Users\Matias Lopez\Documents\GitHub\CCAddons-Testing\FaceSurveillance\FaceSurveillance\Main.cs:line 155
InnerException:
which, from what I've seen, means there is a problem with the solution platforms not matching or something.
Now, the problem is, I need the plugin to be built for AnyCPU, not x64, since iSpy won't even accept it as a valid plugin if not. What can I do to get my C++ dll to be run from the plugin?
Ok, I misunderstood completely what was going on. iSpy is built for x86 because it uses FFMPEG for x86(I honestly have no idea why they would do this), so I can simply build my plugin for x86 and be done with it.
Instead of using a managed C++ project I reverted to using PInvoke and making a wrapper class in the C# project. Problem solved.
I am just looking into compilers and I was wondering is it possible to compile both c# and c++ files from a Java Application (e.g. to compile java from a java application you can use the JavaCompiler API). I have looked online for this but all i can find is ways to compile java files from c# and c++ and not the other way around.
If so, what API's can you use for this?
If you know the system commands for compiling and executing .cpp files(don't know much about c#) you might want to check out this. It details how to execute system commands from a Java program. Pass the system commands for compiling the required file in Runtime.getRuntime().exec().
Consider learning how to call ant from Java code and using something like this ant enhancement.
Disclaimer: I don't know anything about this product, but found it by searching for "can ant build c++?"
For C# in Windows: compiler (csc.exe) is part of .Net install on Windows and can be found at well known location (like %windir%\Microsoft.NET\Framework\v3.5 for .Net 3.5). The same place also contains MSBuild.exe that can build project files (*.csproj).
Your code may need to provide locations for referenced libraries if using Csc.exe to compile individual files.