Accessing static members of a class from dll - c++

I have application written in C++ that uses SWIG for python integration.
Now under linux/osx when i build swig wrapper it creates so file that is used from application like this.
Py_Initialize();
PyRun_SimpleString("import MoBridge");
PyRun_SimpleString("a = MoBridge.MoBridge()");
PyRun_SimpleString("a.CreateQuadMesh()");
Py_Finalize();
What this does is it imports wrapper MoBridge, then it calls trough wrapper C++ function CreateQuadMesh(). Wrapper roughly looks roughly like this
h file:
#include "MoEngine.h"
class MoBridge
{
public:
MoBridge();
~MoBridge();
void CreateQuadMesh();
};
cpp file:
#include "mobridge.h"
void MoBridge::CreateQuadMesh()
{
MoEngine::CreateMesh();
}
The wrapper calls MoEngine static function and it in turn does what it does.
Now this works great under Linux/osx if I understood it correctly because the way so file is linked.
But under windows I had to create DLL and as far as I found DLL files are loaded differently so they live in different memory from the rest of the application and hence cannot see applications other static methods.
I know that I can use dllexport to expose methods from dll to the rest of the application. But in this case I'm looking on how to allow dll to access rest of the applications static functions in applications memory.
I would appreciate any point in the right direction.

If anyone gets stuck with this I have found solution that will resolve this in both linux, osx and windows.
using shared object *.so will of course work with linux/osx but luckily there is even easier solution to use with SWIG that is really not documented in SWIG but it's documented in python documentation (thank you python!)
For this to work you don't need to create dll or so file from your wrapper but after swig creates your *_wrap.cxx file you should include it in your project and before calling Py_Initialize() you import your module like this.
PyImport_AppendInittab("_MoBridge", PyInit__MoBridge);
Then you can use as previously mentioned:
Py_Initialize();
PyRun_SimpleString("import MoBridge");
PyRun_SimpleString("a = MoBridge.MoBridge()");
PyRun_SimpleString("a.CreateQuadMesh()");
Py_Finalize();
And basically since you have your *_wrap.cxx in your project and python is essentially living within your application since you initialised it you have exactly same behaviour like if you have used so in linux/osx except this work on all three platforms.
Cheers!

Related

Use NetCDF4-C in Unity

this is my first time posting (after lurking for years).
A project I will be tackling is to use NetCDF4 (.nc) files in Unity on Windows. I will be using Unity 5.4.0f3 and Windows 10, and I have developed in Unity before and am familiar with C# and JavaScript, but NetCDF only has C, Java, and Fortran APIs, although there are wrappers in Python, C++, and others (source: https://www.unidata.ucar.edu/publications/factsheets/current/factsheet_netcdf.pdf).
So my specific question is how do I call NetCDF4-C functions (nc_get_vara_float(), nc_open, etc) in C# for use in Unity?
What I've tried so far:
To start, I googled specifically for NetCDF4-C + Unity tutorials/attempts, but did not find anything, so instead I have been looking into the compatibility of calling C functions from C#. I am currently working on a project on Linux with NetCDF4-C and written custom wrapper functions for the netcdf.h functions, so I was hoping I could reuse my code there.
I attempted to follow this SO post (Is it possible to call a C function from C#.Net) but get an error in Unity when trying to Play: "DllNotFoundException: test.so" (my file was named "test.c"). From the comments, it seems Linux uses .so files but Windows uses .dll, and I was not sure how to generate a .dll of a C file.
I looked up another post on that (How to write a DLL file in C?) and downloaded Visual Studio to follow along. While VS was downloading, I looked up how to use GCC to compile (Creating a DLL in GCC or Cygwin?), and used the Bash subsystem ("Bash on Ubuntu on Windows" terminal) but got a handful of errors that indicated the code from the previous link (2nd SO link in this post) were for C++, so I stopped working with GCC.
Once VS finished installing, I went back to trying to use VS to create the .dll, and attempted to combine the solutions from both SO posts (1 and 2) so that I would be able to use the .dll file containing C code in Unity, but to no avail: I get the same error but just with a different extension (and different name on purpose): "DllNotFoundException: Win32Project1.dll".
The code I have is as follows:
test.cs (used in Unity and attaches to a Component):
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
public class test : MonoBehaviour {
[DllImport("Win32Project1.dll", EntryPoint="DisplayHelloFromMyDLL")]
public static extern void DisplayHelloFromMyDLL ();
// Use this for initialization
void Start () {
DisplayHelloFromMyDLL();
}
// Update is called once per frame
void Update () {
}
}
Win32Project1.dll (created and built in Visual Studio):
#include <stdio.h>
extern "C"
{
__declspec(dllexport) void DisplayHelloFromMyDLL()
{
printf("Hello DLL.\n");
}
}

Deploy project without Midas.dll C++

I am trying to make it so I can deploy a firemonkey project which uses Midas.dll onto another machine without having to copy the DLL over as well. This article explains how to do this with a delphi project by including MidasLib in your uses clause like so:
program Project1;
uses
MidasLib,
Forms,
Unit1 in 'Unit1.pas' {Form1};
I am not very familiar with delphi, but I assume that in C++ I would want to use an #include statement in places of the uses statement. Since MidasLib is a .pas file, I assume I am supposed to include Midas.hpp. However, even though I include Midas.hpp in the file that is using it, I still get an exception saying "Midas.dll not found."
How can I deploy my project without having to copy the Midas.dll file over with it?
You should also link the static library and call the RegisterMidasLib function:
#include <Midas.hpp>
// or use the Project Manager's "Add to Project" option
#pragma comment(lib, "midas.lib")
extern "C" __stdcall DllGetDataSnapClassObject(REFCLSID, REFIID, void **);
void InitMidas()
{
#pragma startup InitMidas 254
RegisterMidasLib(DllGetDataSnapClassObject);
}
Further details here.

c++ And lua-how to begin?

im trying out other languages.
Got VB2013 and LuaForWindows 5.1 What is the most basic file structure to run a .lua file in my program??
I have currently done http://www.youtube.com/watch?v=w51pftzS1_8 includes part, made a .h file that looks like this
#ifndef __LUA_INC_H__
#define __LUA_INC_H__
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#endif // __LUA_INC_H__
and a Run.cpp like this
#include <iostream>
#include <conio.h>
#include <iostream>
#include "LuaInc.h"
using namespace std;
int main()
{
int iErr = 0;
lua_State *lua = lua_open(); // Open Lua
luaopen_io(lua); // Load io library
if ((iErr = luaL_loadfile(lua, "test.lua")) == 0)
{
// Call main...
if ((iErr = lua_pcall(lua, 0, LUA_MULTRET, 0)) == 0)
{
// Push the function name onto the stack
lua_pushstring(lua, "helloWorld");
// Function is located in the Global Table
lua_gettable(lua, LUA_GLOBALSINDEX);
lua_pcall(lua, 0, 0, 0);
}
}
lua_close(lua);
_getch();
return 0;
}
the test.lua file is in the vb213 projects dir/MYPROJECT/MYPROJECT
and looks like this
function helloWorld ()
io.write ("hello World")
end
From VS2013 and Lua for Windows, you are going to have some pain related to getting the right C Runtime Library version in play. Lua for Windows was compiled against an older version of the CRT, that came with VS2005. It may or may not be possible to get VS2013 to link against that older version. Mixing CRT versions is a recipe for much confusion.
The easiest way out is to get a version of the Lua core built for your version of Visual Studio. There are two ways to do that.
Download a version from Lua Binaries. There are pre-built versions of Lua available from the "official" Lua Binaries distribution. It can be had for 32-bit and 64-bit builds, for Windows, and for other platforms.
Build Lua yourself as part of your solution. Building your own Lua51.dll is straightforward, the default configuration is sensible. It mostly amounts to including almost all the .c files in a DLL project. Note that lua.c is not part of the DLL, that is the source to lua.exe. Similarly, luac.c is not part of the DLL, it is the source to luac.exe which does require some care to build yourself; but you aren't likely to need it.
Either way, you need to pay attention to some details.
The Lua API is a C API, not C++. So if you insist on making your application be a C++ application, you should wrap the inclusion of the Lua header files inside of an exern "C" block:
extern "C" {
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
In principle, you can build the Lua core as C++ instead. The core is written in a clean C flavor that is also a subset of C++, and is tested when compiled as C++. However, if you go that route then you must build any binary modules yourself against your C++ linkage, and that way can lie madness if you depend on many community supplied modules.
I believe that all of the builds available at Lua Binaries are compiled as C, not C++, so the extern "C" declaration will be required with those.
Well, for starters, I would recommend scratching c++ and switching to lua as your primary programming language. It is quite messy to call lua functions from with c++, at least that is my experience. Once you understand enough of Lua, THEN call c/c++ functions from Lua via dll or other file/system formats. I was torn between learning python or c/c++ and I chose python. From there I learned about Lua and loved it more than python. Again this is just my experience and suggestion. Now to answer your question, why run Lua in C++? Lua is based on the C API, so I would just use raw C or just stick with C++. I say this only because Lua is technically no different than a watered down version of C. However, Lua is not "watered down" any more, as it can be used as a fully operational standalone programming language.

LoadLibrary fails with error 203: The system could not find the environment option that was entered

I created a c# class library. I want to load this .dll in my win32 console application, because I have exported one function from the c# class library to unmanaged code and I don't know of any other way to call that function now.
But LoadLibraryA is giving me that error, what can it mean? Googling didn't help me at all.
Used this to export the function to unmanaged:
https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports#TOC-C-:
EDIT: Here is the code, sorry I didn't include it at first because it's as barebones as it gets:
using System;
using RGiesecke.DllExport;
using System.Runtime.InteropServices;
namespace ManagedLibrary
{
public class Test
{
[DllExport(CallingConvention = CallingConvention.Cdecl)]
public static void test()
{
Console.WriteLine("HI");
}
}
}
Looks like the unmanaged exports nuget tool doesn't work for me, the .dll loading errors were mostly obscure and unrelated as it seems (although I did switch to my home computer now)
After I have manually added the exports IL statement as described here:How do you export a method in a CIL DLL so that a native program can call it? I was able to call the C# code just fine.

Qt: Adding native OS Specific code to project

My project is a Qt application written in C++, running on Windows, OS X and Linux. There is a certain area Qt doesn't cover in its abstraction: Iterating other application windows active on the desktop, and returning their names, their 'handles' and icons.
I have OS specific code to do just that.
Pure Win32/C++ on windows
Objective-C on OS X
and some X11 c++ code for linux
I'd like to build my own abstraction that would utilize those OS Specific native snippets to provide it the runtime data it needs.
So, I'd have to have objective-C code build and run with my OS X build
Win32/c++ with windows
and similar with Linux
Let's focus on Mac, just for this example. How do I combine an objective C class into my Qt C++ project? how do I call it from C++? Are there any samples where I can see how it's done?
Ideally I would like to have the OS specific code in the project, and not build separate shared libraries to be linked in, although this is an option if nothing else can be done.
I suppose I would create shared libraries in this situation. Anyway, what I'm about to suggest is an idea, but should work.
By using qmake capabilities, I would create a pro file with different configurations for each platforms, where each configuration (CONFIG variable) includes different sources (this is if you don't want to use simple ifdef's. What I commonly do is create a common header, and different implementations for each platform in a different cpp files. For instance:
/* platformaspecific.h */
class PlatformSpecific : public QObject
{
PlatformSpecific(QObject* parent = 0);
QList<void*> getHandleForWindows(...);
void doSomethingPlatformIndependent();
...
};
/* platformspecific_x11.cpp */
PlatformSpecific::PlatformSpecific(QObject* parent) : QObject(parent)
{
...
}
PlatformSpecific::getHandleForWindows(...)
{
...
}
...
/* platformspecific_win.cpp */
PlatformSpecific::PlatformSpecific(QObject* parent) : QObject(parent)
{
...
}
QList<void*> PlatformSpecific::getHandleForWindows(...)
{
...
}
/* platformspecific_common.cpp (if needed) */
void PlatformSpecific::doSomethingPlatformIndependent()
...
and so on...
Then, in your .pro file, you use different scopes and include the source files according to their related CONFIG.
CONFIG += X11
X11 {
SOURCES += platformspecific_x11.cpp
}
else:WIN {
SOURCES += platformspecific_win.cpp
}
...
SOURCES += platformspecific_common.cpp
After this, for the part including Objective-C you'll have to use Objective-C++. You can mix C++ and Objective-C quite easily with Objective-C++, only some things are not allowed, like extending C++ classes with Objective-C and so on... You can find whatever you need to program using Objective-C++ in the Apple Dev Center. I don't know how good is programming in Objective-C++ using Qt Creator, but anyway you can always create a Xcode project from the .pro file using qmake: read this http://doc.qt.io/archives/qt-4.7/qtmac-as-native.html#development-tools.
By using this approach, or something similar it should be quite comfortable to work.
I would recommend making them static libraries and linking them in. It makes the code simple and direct. It adds the complexity to the build, but generally speaking, it is all or nothing. Once you get it working, there aren't any gotchas.
Things like preprocessor defines work, but when they break it isn't always obvious to the developer why.