How can I debug Lua 5.2.2 code that is embedded inside of my C++ application?
I have already taken a look at this question and all the IDEs provided in it deal with 5.1 and lower and when I try to use them with 5.2.2 they crash.
You should be able to debug your application using ZeroBrane Studio by following instructions for Lua 5.2 debugging. Note that you'll need to have luasocket compiled against Lua5.2. (The crash you see is likely because your application loads luasocket that is compiled against Lua5.1, which in turn loads Lua5.1 DLL or fails to find required symbols.)
If you don't want to compile luasocket, you can get binaries for Windows/OSX/Linux from this folder and its subfolders; just make sure that these libraries are in LUA_CPATH before any folders that may have luasocket compiled against Lua5.1.
[Updated based on chat discussion] The reason you may be getting multiple VM issue is that your app is probably statically compiles Lua interpreter. You then load luasocket (directly or through mobdebug), which is compiled against lua52.dll, which loads another copy of the interpreter. To avoid this you have two choices: (1) compile luasocket into your app the same way you include lua interpreter itself; you won't need anything else except one mobdebug.lua file to debug your app, or (2) use proxy dll; it will look like lua52.dll, but will actually proxy your calls to your statically compiled lua library, avoiding problems with multiple VMs. The proxy dll is for Lua 5.1, but you can tweak the script to make it work for Lua 5.2.
(If your interpreter is not statically compiled, you may still get two interpreters if the Lua DLL you load is named differently from lua52.dll.)
In response to OP's commented request, here's how you should open the lua standard library "base" from C++:
#include "lua.hpp"
//...
int main ()
{
lua_State* L = luaL_newstate();
luaL_requiref(L, "base", luaopen_base, 0);
// ...
int error = luaL_loadfile(L, mainLua);
lua_call(L, 0, 0);
lua_close(L);
}
Note that you can open all the standard libraries at once by replacing:
luaL_requiref(L, "base", luaopen_base, 0);
with
luaL_openlibs(L);
The Lua 5.2 reference manual Section 6 has more info about this.
Related
I am using Eclipse kepler for AVR development.
The code that I have is C (Open Source), and I've gotten it adjusted so it runs perfectly. My target is an ATmega2560, in the form of an arduino mega2560.
Using the arduino board is strictly for hardware convenience; we are developing the hardware to be a custom board with most of the core arduino mega2560 components.
I need to use several libraries with this project that are only available as arduino libraries, namely libraries for an e-paper screen (from seeedstudio) and Nordic's BLE nRF8001.
If I create a new arduino project using the plugin in eclipse, I can build and run the tests for the arduino libraries perfectly.
When I try to merge the 2 code bases together, I can't seem to call the functions in the added arduino libraries - if I call them the compiler throws a linking error.
Building target: Virgin2ManualArdInsert.elf
Invoking: AVR C Linker
avr-gcc -Wl,-Map,Virgin2ManualArdInsert.map -mmcu=atmega2560 -o "Virgin2ManualArdInsert.elf" ./avr/adc.o ./avr/eeprom.o ./avr/lcd_and_input.o ./avr/main.o ./avr/strings.o ./avr/unimplemented.o ./avr/usart.o ./aes.o ./baseconv.o ./bignum256.o ./ecdsa.o ./endian.o ./fft.o ./fix16.o ./hash.o ./hmac_sha512.o ./messages.pb.o ./p2sh_addr_gen.o ./pb_decode.o ./pb_encode.o ./pbkdf2.o ./prandom.o ./ripemd160.o ./sha256.o ./statistics.o ./stream_comm.o ./test_helpers.o ./transaction.o ./wallet.o ./xex.o
./avr/main.o: In function `main':
main.c:(.text.startup.main+0xc): undefined reference to `writeEink'
collect2: error: ld returned 1 exit status
makefile:53: recipe for target 'Virgin2ManualArdInsert.elf' failed
make: *** [Virgin2ManualArdInsert.elf] Error 1
As a test, I'm just trying to call a basic "write to display" call in eInk.cpp from main.c:
extern "C"{
void writeEink()
{
EPAPER.begin(EPD_SIZE); // setup epaper, size
EPAPER.setDirection(DIRNORMAL); // set display direction
eSD.begin(EPD_SIZE);
GT20L16.begin();
// int timer1 = millis();
EPAPER.drawString("testing", 10, 10);
EPAPER.drawNumber(12345, 60, 40);
EPAPER.drawFloat(-1.25, 2, 80, 65);
EPAPER.display(); // use only once
}
Is a static library built from the arduino cores the way to go here? I've tried it (though it seems most of the procedures are outdated) and the libraries do not want to link/be called.
What is the correct procedure for including C++/Arduino calls in my C code?
I've tried using extern "C" {function()}; in my .cpp files and .h files but to no use.
Thank you for any help or pointers to where I can figure it out for myself.
You can try to compile your C code as C++ by simply renaming the files to *.CPP, but chances are that you have to modify your code to make it compile as C++ code. There are things that are allowed for C, but not for C++ (like calling functions that are not declared).
The other solution is to wirte wrappers around the C++ functions that you want to use from C.
You have to consider two limitations of C against C++:
C is not object oriented
C does not support overloading of functions
This example for Serial.print() shows how you can handle this with a wrapper:
extern "C" void SerialPrintInteger( int value )
{
Serial.print( value );
}
In this example you would write similar functions like SerialPrintFloat(), SerialPrintString() etc.
The extern "C" prefix tells the compiler to create the function in a way that makes it callable from C.
The error you received above isn't a compiler error, it's a linker error. I haven't used Eclipse for Arduino development, I just stick with the Arduino IDE, but the standard Arduino projects expect all of your code to be in a single source file, which it compiles and then links with the Arduino libraries. Arduino programs don't have a C/UNIX-style "main" function, the standard functions are "setup" and "loop."
I recommend going back to one of the Arduino example programs, blink for instance, and watching the console log as Eclipse compiles and links the program. What's happening here is:
The C/C++ compiler compiles your source code, including setup(), loop(), and any other functions you have created, into an object file.
The Linker links this single object file with the Arduino runtime, and any Arduino libraries you have specified. The output of this is an image of the program, in your example above it's trying to make 'Virgin2ManualArdInsert.elf'.
The uploader (probably avrdude) loads this image into your Arduino and resets it.
The Arduino comes out of reset and runs your new code.
If your program is reasonably small, say not more than a few hundred lines, just put all the functions in the one source file, then you won't have to learn how to drive the linker.
If you need, for some reason, to have the sources in a separate file (maybe they're shared with another program, or another platform), then you'll have to learn how to get Eclipse to link the object files from your multiple source files. This may just involve adding the sources into your Eclipse project properly, or you may have to write a Makefile or something similar.
As for C vs C++ source code, you can usually drop a C function into a C++ source file and compile it. There are a few differences, but this way you don't need to worry about "C" linkage or any of that silliness.
There is my problem:
All the code is in C++11.
Part 1
I've build a library (named socket).
somwhere in the code, I declare a function:
namespace ntw {
extern int dispatch(int id,Socket& request));
}
This function is user defined (most of the case, simply a big switch)) and by this way the body of it, is not define in the socket lib.
I use this function in server.cpp (which is part of the socket lib).
All is fine under linux, it build the .so perfectly.
But under windows it create a
undefined reference to ntw::dispatch(int,Socket&)
So the .dll is not build.
Part2
I create the main program that use the socket lib.
And in this code, I make :
namespace ntw {
int dispatch(int id,Socket& request)){
/// some code
return ...;
}
}
finaly
So now, that i want is:
the user define int dispatch(int id,Socket& request)) have to be call by the socket libary.
Under Ubuntu, all is fine (coppilation, adn run),
but under windows .... it's the hell.
What can I do to make it work under windows xp and over ?
linux
Ubuntu 12.04, gcc 4.8.1
windows
windows xp, mingw 4.8.1
code
github: https://github.com/Krozark/cpp-Socket
It use cmake (if someone want to try).
What you are attempting won't work on Windows which has a quite different linking model from Linux. You need run time binding. I think you want the function to be provided by the host executable. In which case you need the host to export it with either a .def file or __declspec(dllexport). And then run time binding like this:
HMODULE hMod = GetModuleHandle(NULL); // gets host executable module handle
void *fn = GetProcAddress(hMod, FunctionName);
You can then cast fn to an appropriately declared function pointer before calling the function.
This is probably a reasonable approximation to how your Linux code operates. But it's not a very natural way to operate on Windows. More normal would be for the host to register callback functions or interfaces with the library. Once the host has informed the library of its callbacks, the library can use them.
I built Qt from source (dlls) and am trying to build an application that uses the Qt dlls. I don't have a lot of experience with C++ so I'm running into what I'm sure is a very basic issue.
My builds are failing on the includes with errors like so:
Fatal error: QNetworkProxy: No such file or directory
Here is the g++ command I am using (I also used -L to add the correct folder to the lib path, but that also didn't work):
g++ -l..\..\wkqt\bin\QtCore4.dll -l..\..\wkqt\bin\QtNetwork4.dll -l..\..\wkqt\bin\QtWebKit4.dll -I..\include -Ishared -Ipdf -Ilib -Iimage -o ..\bin\wkhtmltopdf.exe pdf\*.cc lib\*.cc image\*.cc shared\*.cc
I tried in Visual Studio as well (assuming it wouldn't build, but I wanted to see if I could at least include the Qt dlls from there properly) and I am getting the same errors. Am I doing something wrong with the way I am compiling with g++? If I am linking with the Dlls properly then what is the proper way to use Qt functions from my code?
To clarify, I am not looking for how to properly use Qt. My question is: what is the proper way to use functions defined in any Dll from native C++ code? I apologize if this is a very basic question, but I'm unable to find a clear answer on Google and I don't have any experience with C++ and including third party libraries for use from C++ code.
DLLs can be used by dynamicly loading them and calling their used functions.
to call the exposed functions first define their syntax in the begining
suppose function is syntax is
BOOL MyFunction(int a,char* pszString)
then define syntax
#typedef BOOL (WINAPI *PMYFUNCTION)(int a,char* pszString)
then make object
PMYFUNCTION pfnMyFunction;
and get valid pointer by calling GetProcaddress after loadlibrarycall
HMODULE hlib= Loadlibrary("c:\\Mylib.dll");
if(hlib)
{ pfnMyFunction = (PMYFUNCTION)Getprocaddress(hlib,"MyFunction"); }
Hope this helps...
I am trying to communicate with an oscilloscope over USB with NI-VISA 5.1.1. My 32-bit application is written in the Qt framework using C++ and the MinGW compiler (standard Qt 4.7 SDK).
My application has no problems communicating with the device when I statically link to visa32.lib. My dynamically linked code also runs fine on a Windows 7 64-bit platform, but crashes on two different computers running on Windows XP SP3 (32 bit). I have traced the line of code that causes the crash (it is the first call to viWrite).
The issue seems to be related to setup of global variables in the DLL itself. This might explain why it works in Windows 7 since in that case the 32-bit DLL file is only a stub which calls a 64-bit VISA DLL file.
This is how I dynamically link to the exported functions:
typedef long (*tviRead)(ViSession, ViPBuf, ViUInt32, ViPUInt32);
typedef long (*tviWrite)(ViSession, ViBuf, ViUInt32, ViPUInt32);
QLibrary visa32("visa32"); // Qt wrapper for LoadLibrary
if (!visa32.load()) throw "Unable to load visa32.dll";
pviWrite = (tviWrite) visa32.resolve("viWrite");
pviRead = (tviRead) visa32.resolve("viRead");
If I call the following (where the vi prefixed function are statically linked and pvi ones are runtime linked),
status = viOpenDefaultRM(&rm);
status = viFindRsrc(rm, query, &list, &itemCnt, desc);
status = viOpen(rm, desc, VI_NULL, VI_NULL, &vi);
status = pviWrite(vi, (ViByte*) idn, 5, &retCnt); // Crash right here
status = pviRead(vi, (ViByte*) id, sizeof(id), &retCnt);
everything works perfectly. However changing any of the three setup function to runtime linked causes a segmentation fault when calling pviWrite. There aren't AFAIK any other functions exported by the DLL to "setup global variables", in fact I can't see DllMain exported using the Dependency Walker tool. Has anyone ever runtime linked to visa32.dll successfully? I can't find any examples on the Internet.
I suspect you have the following problem:
http://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx
Scroll down to the remarks section, and look for "Visual C++": if the DLL contains _declspec-style thread local storage you can only load it dynamically in Vista or later.
I'm trying to achieve the same thing but apparently, for XP, we are simply out of luck...
I am converting my project to use DLLs and am trying to break apart my Singleton class to avoid using templates.
My class, LudoMemory, originally inherited from Singleton. I am trying to give it the functions to destroy and create itself now and have my main engine not rely on the Singleton.
I have written a simple destroy method like such:
LudoMemory *memory_Singleton = NULL;
void LudoMemory::Destroy()
{
LUDO_SAFE_DELETE(m_Singleton)
}
and upon running the program (no compiler errors) I recieve this error:
The procedure entry point
?Destroy#LudoMemory##SAXXZ could not
be located in the dynamic link library
LudoCore.dll
LudoCore is the project that LudoMemory belongs to. Why is this happening? How can I solve it?
you don't have multiple versions of ludocore.dll on your system, do you?
Procedure entry points errors usually mean: you compiled your project against ludocore.lib version x, and when running the program, it uses ludocore.dll version y, and version y does not define LudoMemory::Destroy().
Jacob's answer about multiple DLL versions seems likely.
Also, with some build systems, you must explicitly list which functions will be exported in a DLL.
Research your build environment, and see if you must provide a list of methods to be exported as an entry-point.
In Visual Studio build environment, also you could try by disabling the References in Linker Optimization Settings [ No(/OPT:NOREF)]