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");
}
}
Related
Steps to reproduce:
Install a version of Visual Studio (I used VS Community 2022). Install OpenCASCADE 7.6.0.
Create a C++ .NET CLR project using Visual Studio 2022 targeting .net6.0.
Change settings to include OpenCASCADE header and library files.
Edit the main header by replacing the code within it with below:
#pragma once
//for OCC graphic
#include <OpenGl_GraphicDriver.hxx>
//wrapper of pure C++ classes to ref classes
#include <NCollection_Haft.h>
namespace ClrClsLibDotNetCoreMwe {
public ref class Class1
{
// TODO: Add your methods for this class here.
};
}
Attempt to build.
Issue: The build fails with the following complain:
1>C:\OpenCASCADE-7.6.0-vc14-64\opencascade-7.6.0\inc\NCollection_DefaultHasher.hxx(34,1): error C2872: 'HashCode': ambiguous symbol
1>C:\OpenCASCADE-7.6.0-vc14-64\opencascade-7.6.0\inc\NCollection_DefaultHasher.hxx(34,1): message : could be 'HashCode'
1>C:\OpenCASCADE-7.6.0-vc14-64\opencascade-7.6.0\inc\NCollection_DefaultHasher.hxx(34,1): message : or 'System::HashCode'
What fixes the problem:
Either Targeting .NET Framework instead of .NET Core (/clr instead of /clr:netcore).
Or removing one of the headers.
Please see if there is a way where I can keep both the headers and target .NET Core?
I have looked around for a possible solution before posting this question here. A promising solution was to disable implicit usings. However, that didn't pan out.
I had the same problem.
In my case, the "using namespace System;" included in the header file. The text caused the problem.
Thanks!
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!
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.
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.
This is the first question I have found myself not being able to get to the bottom of using my normal googling/stack overflowing/youtubing routine.
I am trying to compile a minimal Lua program inside of a C++ environment just to ensure my environment is ready to development. The Lua language will be later used for User Interface programming for my C++ game.
First some basic information on my environment:
Windows 7 64-bit
Visual studio 2010
Lua for Windows 5.1 (latest build I could download from google code)
Here is the code I am trying to compile:
// UserInt.cpp : Defines the entry point for the console application.
//
#pragma comment(lib,"lua5.1.dll")
#include "stdafx.h"
#ifndef __LUA_INC_H__
#define __LUA_INC_H__
extern "C"
{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
int _tmain(int argc, _TCHAR* argv[])
{
lua_State * ls = luaL_newstate();
return 0;
}
#endif // __LUA_INC_H__
Here is the Error I am getting:
1>UserInt.obj : error LNK2019: unresolved external symbol _luaL_newstate referenced in function _wmain
1>c:\users\deank\documents\visual studio 2010\Projects\UserInt\Debug\UserInt.exe : fatal error LNK1120: 1 unresolved externals
Things I have tried:
I have read about lua_open()(and several other functions) no longer being used so I tried the newstate function instead. I get the same error. This was more of a sanity check than anything. I am using 5.1 and not 5.2 so I do not think this really matters.
I have also read this thread Cannot link a minimal Lua program but it does not seem to help me because I am not running the same environment as that OP. I am on a simple windows 7 and visual studio environment.
The top pragma comment line was something I saw in yet another thread. I get the same error with or without it.
I have gone into my visual studio C++ directories area and added the lua include to the includes and the lua lib to the libraries.
So it seems like my program is seeing the .h and seeing the symbol. But for some reason it is not getting the .cpp implementation for the functions. This is why I was hoping including that .dll directly would help fix the problem, but it hasn't.
So, I feel like I have exhausted all of my options solving this on my own. I hope someone is able to help me move forward here. Lua looks like an awesome language to script in and I would like to get my environment squared away for development.
I hope it is just some silly error on my part. I believe I have provided as much information as I can. If you need more specifics I will update with info if I can provide it.
Edit1
Tried the solution in this Can't build lua a project with lua in VS2010, library issue suspected
That did not work either.
You'll need to have the library (.LIB) file and add that to VS. Use Project > Properties and go to Linker > Input and add the full .lib filename to the "Additional Dependencies" line. Note that the .LIB is different from the .DLL.
Personally, I prefer adding the source code to my project, over referencing the dynamic link library. The following procedure will let you do as such.
Download the source code ( http://www.lua.org/ftp/ ), uncompress it.
In Visual Studio, choose File > New > Project and choose Visual C++, Win32, "Win32 Console Application".
In your project in Visual Studio, add all the source code, except luac.c. Also delete the main() function out of the file that VS created for you. This is usually given the name of the project you specified with the .cpp file extension. You could just remove this file all-together from the project.
Build and Run.
This is the Lua console