C++ dll in hololens - c++

I am working creating a hololens application using a native code dll based on c ++. The problem comes when I add it in the unity project (plugins / WSA / x86).
When generating the UWP solution in Visual Studio I get a failure of DllNotFound.
From what I have been able to read, it is necessary to create a UWP library to use it in my application. That library must contain my native code. The truth is that I'm not sure how to do that. Is there any way to stop my dll based on c ++ on a UWP dll ??
error: System.DllNotFoundException: Unable to load DLL 'nativoHololensPrueba.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E).
C++
SOURCE:
#include <iostream>
#include <stdio.h>
#include <memory>
#include "Header.h"
__declspec(dllexport)
int testo() {
return 10;
}
HEADER:
extern "C" {
__declspec(dllexport)
int testo();
}
c#
[DllImport("nativoHololensPrueba")]
public static extern int testo();
// Use this for initialization
public GameObject texto;
void Start () {
texto.GetComponent<TextMesh>().text = "Cambiando el nombre " + testo();
}

I also had this and I solved it by compiling the dll on ARM64 (or ARM) with /MT flag.

Related

Requiring C++ DLL from Lua gives an error

I am trying to compile C++ code to a DLL file to use with Lua. To do this, I am using Visual Studio 2022 with Windows 10. My goal is to use the Lua require(modname) function to require my DLL and use the C++ methods in Lua. For now the DLL and the main.lua files are in the same directory. What is actually happening is that I get an error message saying:
error loading module 'lgf' from file 'lgf.dll': The specified module could not be found.
with the Lua code:
package.cpath = "?.dll;"..package.cpath
create = require("lgf")
My main.cpp file contains the following:
#include <iostream>
#include <string>
#include <window/include/window.hpp>
#include <font/include/font.hpp>
#include <image/include/image.hpp>
#include <keyboard/include/keyboard.hpp>
#include <mouse/include/mouse.hpp>
#include <rectangle/include/rectangle.hpp>
#include <lua/lua.hpp>
#define LIB
SDL_Window* sdlWin;
SDL_Renderer* sdlRen;
window win(sdlWin, sdlRen);
static const luaL_Reg lib[] = {
{"create", window::create},
{"isCloseRequested", window::isCloseRequested},
{"sync", window::sync},
{"update", window::update},
{"setVSync", window::setVSync},
{"setIcon", window::setIcon},
{"clearScreen", window::clearScreen},
{"render", window::render},
{"windowChangeColor", window::changeColorRGB},
{"close", window::close},
{"createRectangle", rectangle::create},
{"changeRectangleColor", rectangle::changeColor},
{"drawRectangle", rectangle::draw},
{"mouseButtonUp", Mouse::mouseButtonUp},
{"mouseButtonDown", Mouse::mouseButtonDown},
{"keyup", Keyboard::keyup},
{"keydown", Keyboard::keydown},
{"loadImage", ImageLoader::loadImage},
{"drawImage", ImageLoader::drawImage},
{"loadFont", FontLoader::loadFont},
{"loadText", FontLoader::loadText},
{"renderText", FontLoader::renderText},
{NULL, NULL}
};
extern "C" __declspec(dllexport) int luaopen_lgf(lua_State* L) {
luaL_newlib(L, lib);
return 22;
}
I am creating a simple graphics library. My dependencies are SDL2 and (of course) Lua.
I have tried creating an entry point (main) for the file, and I still get the same message. Let me know if I should include my other .cpp files in here.

c++/cli dll wrapper for native c++ to be used in LabView

I'm trying to write a c++/cli wrapper for IO Industries Core2 DVR, which will then be used by LabView. The company provided a SDK with with all the headers (written in c++) and boost library. I've managed to build a wrapper that builds and LabView is able to see the function through the .net pallet.
// ManagedProject.h
#pragma once
#include "core_api_helper.h"
#include "core_api.h"
using namespace System;
using namespace CoreApi;
namespace ManagedProject {
//Setup class
public ref class Setup
{
private:
public:
unsigned int initializeTest();
};
}
// This is the DLL Wrapper.
#include "stdafx.h"
#include "ManagedProject.h"
#include "core_api_helper.h"
#include "core_api.h"
#include "resource.h"
using namespace CoreApi;
using namespace Common;
using namespace ManagedProject;
//Global handles
//A handle to the Core Api
InstanceHandle g_hApi;
//A handle to the Core Api Device Collection
DeviceCollectionHandle g_hCoreDeviceCollection;
unsigned int Setup::initializeTest()
{
try
{
//Initialize the Core API (must be called before any other Core API functions)
//Returns a handle to the Core Api
g_hApi = Instance::initialize();
// get a collection of Core devices
g_hCoreDeviceCollection = g_hApi->deviceCollection();
unsigned int deviceCount = g_hCoreDeviceCollection->deviceCount();
return deviceCount;
}
catch (GeneralException& e)
{
e.what();
return 3;
}
}
However when I run LabView through Visual studio 2015 in debug mode I run into the problem below, and what is returned to LabView is the 3 from the catch block.
First break in debug mode (NULL ptr)
NOTE: InstanceHandle is a shared_ptr
As can be seen the variable is a NULL pointer, the same thing happens for the g_hCoreDeviceCollectoin as well. I think I need to Instantiate it with the new command but am a little unsure as InstanceHandle is a shared_ptr.
Any help would be much appreciated
The C++/CLI has great feature called mixed mode. You can uses both managed and native data types in the same code (in the same C++/CLI class). Try to use object from that SDK written in C++ directly in your wrapper.

Use C++/CLI Library in C++ native code and how to link

I want to use some code that executes a http-post, and because I'm not too familiar with c++ and what libraries you can use, and I am probably too dumb to get libcurl and curlpp to work, I found a link explaining how to use the .net version.
Alright so I created a class. Header File:
public ref class Element
{
public:
Element();
virtual ~Element();
void ExecuteCommand();
};
Class file:
#include "Element.h"
Element::Element()
{
}
Element::~Element()
{
Console::WriteLine("deletion");
}
void Element::ExecuteCommand(){
HttpWebRequest^ request = dynamic_cast<HttpWebRequest^>(WebRequest::Create("http://www.google.com"));
request->MaximumAutomaticRedirections = 4;
request->MaximumResponseHeadersLength = 4;
request->Credentials = gcnew NetworkCredential("username", "password", "domain");
HttpWebResponse^ response = dynamic_cast<HttpWebResponse^>(request->GetResponse());
Console::WriteLine("Content length is {0}", response->ContentLength);
Console::WriteLine("Content type is {0}", response->ContentType);
// Get the stream associated with the response.
Stream^ receiveStream = response->GetResponseStream();
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader^ readStream = gcnew StreamReader(receiveStream, Encoding::UTF8);
Console::WriteLine("Response stream received.");
Console::WriteLine(readStream->ReadToEnd());
response->Close();
readStream->Close();
}
If I set the configuration type of this project to Application (exe), and create a new .cpp file where I create an Instance of this Element it works fine.
But my question is: Is it possible to create a .dll/.lib Library from this project and use it in a C++ project without CLI? (I don't want to use ^ for pointers :( )
Even if it's not possible, I have another problem.
When I link the library in a C++/CLI project. I get
unresolved token (06000001) Element::.ctor
unresolved token (06000002) Element::~Element
unresolved token (06000003) Element::ExecuteCommand
3 unresolved externals
the code for main.cpp in the second project is just the following:
#include <Element.h>
int main(){
return 0;
}
Thank you
As Hans Passant already stated: you must compile your C++/CLI code as Dynamic Library in order to be able to consume it from an unmanaged application. CLI/Managed code cannot run from/cannot reside in static libraries.
If you change the C++/CLI library target from Static library to Dynamic library you'll be able to compile successfully your unmanaged C++ application.
One thought from my side:
I think you'll be better if you use mixed mode C++/CLI DLLs to consume the managed functionality - you'll be able to free your consumer application completely from referencing the CLR.
The Header of such mixed mode Wrapper for your Element class would look like this:
#pragma once
#pragma unmanaged
#if defined(LIB_EXPORT)
#define DECLSPEC_CLASS __declspec(dllexport)
#else
#define DECLSPEC_CLASS __declspec(dllimport)
#endif
class ElementWrapperPrivate;
class __declspec(dllexport) ElementWrapper
{
private:
ElementWrapperPrivate* helper;
public:
ElementWrapper();
~ElementWrapper();
public:
void ExecuteCommand();
};
And the implementation would look like this:
#include "ElementWrapper.h"
#pragma managed
#include "Element.h"
#include <msclr\auto_gcroot.h>
using namespace System::Runtime::InteropServices;
class ElementWrapperPrivate
{
public:
msclr::auto_gcroot<Element^> elementInst; // For Managed-to-Unmanaged marshalling
};
ElementWrapper::ElementWrapper()
{
helper = new ElementWrapperPrivate();
helper->elementInst = gcnew Element();
}
ElementWrapper::~ElementWrapper()
{
delete helper;
}
void ElementWrapper::ExecuteCommand()
{
helper->elementInst->ExecuteCommand();
}
Then just compile your Element.cpp + ElementWrapper.cpp to a DLL and use the ElementWrapper.h in your unmanaged applications.

managed c to call an unmanaged c dll , unresolved token

I have 1 native c++ dll, CppApp, another project is managed c++, GatWayLibrary, with /clr
In GatewayLibrary, I called functions from native CppApp dll.
but I got unresolve token errors.
Here are my code snips:
CppApp.h
=========
#ifdef CPPAPP_EXPORTS
#define CPPAPP_API __declspec(dllexport)
#else
#define CPPAPP_API __declspec(dllimport)
#endif
class CPPAPP_API CppApp
{
public:
CppApp();
~CppApp();
ContextManager & contextMgr() { return m_rplContextMng; }
INativeListener* m_listener;
void registerListener(INativeListener* listener)
{
m_listener = listener;
}
...........
}
In separate project, GateWaylibrary, wrap the native dll as
#include "../CppApp/CppApp.h"
#include <vcclr.h>
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma comment(lib, "CppApp.lib")
namespace GatewayLibrary{
//.net equvelant of the argument class
public ref class DotNetEventArg{
internal:
//contructor takes native version of argument to transform
DotNetEventArg(const NativeCPPArgs& args) {
....
...
}
the managed c++ has the linking errors as unresolved tokens for all the function calls from the native c++.
I did include the CppApp.lib as Additional Dependencies
and the directory.
Can anyone please help? many thanks ahead.
Edit:
here is of the place I called the native c++
`GatewayLibrary::EventGateway::EventGateway()
{
nativeCode_ = new CppApp();
//note; using 'this' in ctor is not a good practice
nativeListener_ = new NativeListenerImp(this);
//register native listener
nativeCode_->registerListener(nativeListener_);
}`

Import unmanaged "QT" dll to C# give dllNotFoundException but exists

I am trying to import a dll to a C# console application just to see if I can get a dll to work as a want, when trying this and exporting functions with C-code everything works fine and the functions can be imported in my C# application.
The problem starts when I try to add some kind of linkage to some QT methods in my unmanaged dll. I'm using DllImport to import the functions from the dll.
[DllImport("cDLL.dll", EntryPoint = "_Add#16")]
static extern double Add(double a, double b);
1 - This is how the unmanaged dll (don't look at the functionality of the code, this is just for testing purposes) looks like when it works fine.
main.cpp working
#include <stdexcept>
#include "Windows.h"
using namespace std;
extern "C" __declspec(dllexport) double __stdcall Add(double a, double b)
{
return a + b;
}
extern "C" __declspec(dllexport) const char* getText()
{
return "hello world";//returnBufferString.c_str();
}
BOOL __stdcall DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved) {
return TRUE;
}
2 - When I try to add a help function with some QT code, just an ordinary QString the DllImport starts throwing dllNotFoundException.dumpbin.exe shows all the exported functions as well after including the qt code...
main.cpp dllNotFoundException
#include <QString>
using namespace std;
class testa
{
public:
static char* test()
{
QString a = "hejsan";
return qString2Char(a);
}
static char* qString2Char(QString a)
{
return a.toUtf8().data();
}
};
This is called from the getText() function like this:
string returnBufferString;
extern "C" __declspec(dllexport) const char* getText()
{
returnBufferString = testa::test();
return returnBufferString.c_str();
}
When I try to access the dll from DllImport I get dllNotFoundException in the 2:nd part. How do I solve this? have I missed any dependencies or anything. My dll is build using msvc2010 compiler and the .pro file looks like this:
cDLL.pro
TEMPLATE = lib
CONFIG += dll
QT += core
# Input
SOURCES += main.cpp
I'm stuck...
It doesn't tell you exactly what DLL it cannot find. Which is almost surely not your DLL, it is one of the DLLs that QT requires. You'd have to copy them to the EXE folder as well. If you have no idea and can't find it in the Nokia documentation then you can find out with SysInternals' ProcMon utility.
However, in this scenario you surely want to link QT into your DLL since the odds that those DLLs can be shared are small. Use this SO question for guidance in setting up your QT project.
You need to put the DLL in the same folder as your executable.
See http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586%28v=vs.85%29.aspx