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.
Related
One more day, one more dumb question on stackoverflow, please excuse me.
The idea was to make dll and then import it to another project to use it there, but after including dll header file in second project and writing paths to the .lib and header files I still have these errors:
E0070 incomplete type is not allowed prjct-1 D:\projects-vs\firstTryWT\prjct-1\prjct-1.cpp 33
C2027 use of undefined type 'stmr::MathProblem' prjct-1 D:\projects-vs\firstTryWT\prjct-1\prjct-1.cpp 33
C2079 'problem' uses undefined class 'stmr::MathProblem' prjct-1 D:\projects-vs\firstTryWT\prjct-1\prjct-1.cpp 33
C3493 'problem' cannot be implicitly captured because no default capture mode has been specified prjct-1 D:\projects-vs\firstTryWT\prjct-1\prjct-1.cpp 35
I've tried to rebuild, change some code till I understand that I either already did what is needed or I don't know what is needed. Anyway, here is the code:
Dll header file:
#pragma once
#ifdef STMR_EXPORTS
#define STMR_API __declspec(dllexport)
#else
#define STMR_API __declspec(dllimport)
#endif
#include <vector>
#include <string>
namespace stmr
{
class STMR_API MathProblem;
class STMR_API Operation;
}
Definitions of both classes have STMR_API keyword. I have 'STMR_EXPORTS' in C/C++ -> Preprocessor and '$(OutDir)$(TargetName).lib' in Linker -> Advanced -> Import Library so that I have the import lib generated.
main cpp of the project which is supposed to use the dll:
#include <Wt/WApplication.h>
#include <Wt/WBreak.h>
#include <Wt/WContainerWidget.h>
#include <Wt/WLineEdit.h>
#include <Wt/WPushButton.h>
#include <Wt/WText.h>
#include "stmrLib.h"
class HelloApplication : public Wt::WApplication
{
public:
HelloApplication(const Wt::WEnvironment& env);
private:
Wt::WPushButton* button_m;
Wt::WText* summary_m;
};
HelloApplication::HelloApplication(const Wt::WEnvironment& env)
: Wt::WApplication(env)
{
button_m = root()->addWidget(std::make_unique<Wt::WPushButton>());
summary_m = root()->addWidget(std::make_unique<Wt::WText>());
stmr::MathProblem problem = stmr::MathProblem(problemText_m->text().narrow());
auto solving = [this] {
summary_m->setText("This equals " + std::to_string(problem.solve()));
};
button_m->clicked().connect(solving);
}
int main(int argc, char** argv)
{
return Wt::WRun(argc, argv, [](const Wt::WEnvironment& env) {
return std::make_unique<HelloApplication>(env);
});
}
I have correct path to the .lib file for dll in Linker -> General -> Additional Library Dependencies and stmr.lib/stmrd.lib in Linker -> Input -> Additional Dependencies for Release/Debug
Not sure if the problem in exporting or importing of the dll.
Feedback about question quality is appreciated.
In C++ (prior to modules) the header file needs to expose enough information about a class for another cpp file to create the object or use the type.
You have just forward declared it, which is enough to make pointers or references to the type and nothing else.
These errors have nothing to do with linking or DLLs or exports.
All compilation units that need to make instances or otherwise call methods of your types need to see the class definition. Put it in the headerfile. Method definitions can be in cpp files and exported.
The pImpl pattern may help you hide details, if you do not want to expose them.
I am trying running c++ file on plugin IOS (not ios app). First I create cpp file
Greeting.cpp
#include "Greeting.hpp"
Greeting::Greeting() {
greeting = "Hello C++!";
}
std::string Greeting::greet() {
return greeting;
}
Then I create Greeting.hpp
#ifndef Greeting_hpp
#define Greeting_hpp
#include <stdio.h>
#include <string>
class Greeting {
std::string greeting;
public:
Greeting();
std::string greet();
};
#endif /* Greeting_hpp */
Then I import it into object c file
AgoraRtcEnginePlugin.m
#import "Greeting.hpp"
NSString* newTitle = [NSString stringWithCString:greeting.greet().c_str() encoding:[NSString defaultCStringEncoding]];
result(newTitle);
But when I complile It always throws errors
/agora-flutter-sdk/ios/Classes/Greeting.hpp:13:10: fatal error: 'string' file not found
#include <string>
The problem you have is that you're including C++ in your Objective-C (AgoraRtcEnginePlugin.m = .m extension is Objective-C) file. Objective-C is a layer on top of C and Objective-C is a strict superset of C.
You can't do this unless you use extern "C", etc. There are questions about this:
How to call C++ function from C?
Calling āC++ā class member function from āCā code
etc.
You're not forced to create an C API for you class, because there's also Objective-C++ (.mm extension) and you can use C++ directly in these files.
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.
I've got a little problem. I got a dll C library, a header file, and all other files needed to call this dll. I've tried calling this dll through third party programs and it is working.
However, when I try calling it directly (dynamic linking at load and using the given header file) I always get the linker error 1136 with mydll.lib.
Using the header file:
#include "windows.h"
#include "mydll.h"
void main() {
bool test;
test = CallDll("MyArg");
}
With code in headerfile as below:
extern "C" bool _stdcall CallDll(char* MyArg);
Using dynamic linking at load time:
#include "windows.h"
bool(*CallDll)(char*);
HINSTANCE h = LoadLibrary((LPCSTR)"mydll");
void main() {
CallDll = (bool(*)(char*))GetProcAddress(h, "CallDll");
bool test;
test = CallDll("MyArg");
}
Now what did I do wrong? I doubt the mydll.lib file is broken, because if this were the issue, I couldn't access the dll with a third party program.
Well it was a rather simple solution.
bool(*CallDll)(char*);
HINSTANCE h = LoadLibrary(L"mydll.dll");
void main() {
CallDll = (bool(*)(char*))GetProcAddress(h, "CallDll");
bool test;
test = CallDll((char*)"MyArg");
}
Was all it needed...
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_);
}`