Lua module with Visual Studio - lua

I'm trying to make a Lua module with Visual Studio 2013, the main ccp is here along with the module.hpp and the other include is here.
I changed the main ccp to remove a unneeded include file and two unneeded functions so I get this:
#include <lua.hpp>
#include <GeoIP.h>
#include "module.hpp"
static GeoIP * geoip = NULL;
static int load_geoip_database(lua_State * L)
{
const char * filename = luaL_checkstring(L, 1);
if (geoip) GeoIP_delete(geoip);
geoip = GeoIP_open(filename, GEOIP_MEMORY_CACHE);
lua_pushboolean(L, geoip != NULL);
return 1;
}
static int ip_to_country(lua_State * L)
{
if (!geoip) return luaL_error(L, "missing GeoIP database");
const char * ipaddr = luaL_checkstring(L, 1);
const char * country = GeoIP_country_name_by_addr(geoip, ipaddr);
lua_pushstring(L, (country ? country : ""));
return 1;
}
static int ip_to_country_code(lua_State * L)
{
if (!geoip) return luaL_error(L, "missing GeoIP database");
const char * ipaddr = luaL_checkstring(L, 1);
const char * code = GeoIP_country_code_by_addr(geoip, ipaddr);
lua_pushstring(L, (code ? code : ""));
return 1;
}
static int shutdown_geoip(lua_State * L)
{
GeoIP_delete(geoip);
geoip = NULL;
return 0;
}
namespace lua{
namespace module{
void open_geoip(lua_State * L)
{
static luaL_Reg functions[] = {
{ "load_geoip_database", load_geoip_database },
{ "ip_to_country", ip_to_country },
{ "ip_to_country_code", ip_to_country_code },
{ NULL, NULL }
};
luaL_register(L, "geoip", functions);
lua_pop(L, 1);
lua::on_shutdown(L, shutdown_geoip);
}
} //namespace module
} //namespace lua
Visual Studio throws me the following errors:
1>------ Build started: Project: GeoIP, Configuration: Release Win32 ------
1> Main.cpp
1>Main.obj : error LNK2001: unresolved external symbol _GeoIP_delete
1>Main.obj : error LNK2001: unresolved external symbol _luaL_checklstring
1>Main.obj : error LNK2001: unresolved external symbol _luaL_register
1>Main.obj : error LNK2001: unresolved external symbol _lua_pushstring
1>Main.obj : error LNK2001: unresolved external symbol _GeoIP_country_name_by_addr
1>Main.obj : error LNK2001: unresolved external symbol _lua_settop
1>Main.obj : error LNK2001: unresolved external symbol "void __cdecl lua::on_shutdown(struct lua_State *,int (__cdecl*)(struct lua_State *))" (?on_shutdown#lua##YAXPAUlua_State##P6AH0#Z#Z)
1>Main.obj : error LNK2001: unresolved external symbol _GeoIP_country_code_by_addr
1>Main.obj : error LNK2001: unresolved external symbol _GeoIP_open
1>Main.obj : error LNK2001: unresolved external symbol _luaL_error
1>Main.obj : error LNK2001: unresolved external symbol _lua_pushboolean
1>C:\Users\User\Documents\Visual Studio 2013\Projects\Win32Project1\Release\GeoIP_win32.dll : fatal error LNK1120: 11 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
and I dont know what the errors are meaning, the module has been built before by others so the code should be OK.

Looks like you forgot to configure your build so the linker knows what libraries to link to your module. Looks like you should link to GeoIP DLL and, of course, the Lua DLL. In the project's Properties dialog, look for Linker | General | Additional Library Directories, it must indicate the folder where your Lua DLL is located, and the folder where the GeoIP DLL is located. Then look at Linker | Input | Additional Dependencies, it must indicate the name of the Lua export lib for the Lua DLL (such as lua51.lib), and same for GeoIP (something like libgeoip.lib).

Related

Showing detailed dumps

Hi i'm experimenting with dart ffi and i'm having an issue with the following dump
===== CRASH =====
si_signo=Segmentation fault(11), si_code=1, si_addr=(nil)
version=2.12.0-157.0.dev (dev) (Wed Dec 16 01:04:40 2020 -0800) on "linux_x64"
pid=262571, thread=262578, isolate_group=main(0x373e8c0), isolate=main(0x373f140)
isolate_instructions=17fde20, vm_instructions=17fde20
pc 0x00007f1633a00543 fp 0x00007f1656c1d540 wasm_instance_exports+0x13
pc 0x00007f163ce30505 fp 0x00007f1656c1d578 Unknown symbol
pc 0x00007f163ce3023f fp 0x00007f1656c1d5e0 Unknown symbol
pc 0x00007f163ce25553 fp 0x00007f1656c1d6b8 Unknown symbol
pc 0x00007f163ce2453c fp 0x00007f1656c1d700 Unknown symbol
pc 0x00007f163ce24233 fp 0x00007f1656c1d728 Unknown symbol
pc 0x00007f163ce2419f fp 0x00007f1656c1d750 Unknown symbol
pc 0x00007f163ce240cf fp 0x00007f1656c1d7a8 Unknown symbol
pc 0x00007f163ce2300e fp 0x00007f1656c1d7d8 Unknown symbol
pc 0x00007f163ce22d72 fp 0x00007f1656c1d838 Unknown symbol
pc 0x00007f163ce2276e fp 0x00007f1656c1d870 Unknown symbol
pc 0x00007f1656d8265f fp 0x00007f1656c1d8e8 Unknown symbol
-- End of DumpStackTrace
[exit : sp(0) fp(0x7f1656c1d540) pc(0)]
[dart : sp(0x7f1656c1d550) fp(0x7f1656c1d578) pc(0x7f163ce30505) *dart:ffi_::_FfiTrampoline ]
[dart : sp(0x7f1656c1d588) fp(0x7f1656c1d5e0) pc(0x7f163ce3023f) file:///home/kingwill101/code/wasm-dart/generated_bindings.dart_Wasmer_wasm_instance_exports ]
[dart : sp(0x7f1656c1d5f0) fp(0x7f1656c1d6b8) pc(0x7f163ce25553) file:///home/kingwill101/code/wasm-dart/bin/main.dart_::_helloWorld__async_op ]
[dart : sp(0x7f1656c1d6c8) fp(0x7f1656c1d700) pc(0x7f163ce2453c) file:///home/kingwill101/code/wasm-dart/bin/main.dart_::_helloWorld ]
[dart : sp(0x7f1656c1d710) fp(0x7f1656c1d728) pc(0x7f163ce24233) file:///home/kingwill101/code/wasm-dart/bin/main.dart_::_main ]
[dart : sp(0x7f1656c1d738) fp(0x7f1656c1d750) pc(0x7f163ce2419f) file:///home/kingwill101/code/wasm-dart/bin/main.dart_::_main_main ]
[dart : sp(0x7f1656c1d760) fp(0x7f1656c1d7a8) pc(0x7f163ce240cf) dart:core__Closure#0150898_dyn_call ]
[dart : sp(0x7f1656c1d7b8) fp(0x7f1656c1d7d8) pc(0x7f163ce2300e) dart:isolate_::__delayEntrypointInvocation#1026248_<anonymous closure> ]
[dart : sp(0x7f1656c1d7e8) fp(0x7f1656c1d838) pc(0x7f163ce22d72) dart:core__Closure#0150898_dyn_call ]
[dart : sp(0x7f1656c1d848) fp(0x7f1656c1d870) pc(0x7f163ce2276e) dart:isolate__RawReceivePortImpl#1026248__handleMessage#1026248 ]
[entry : sp(0x7f1656c1d880) fp(0x7f1656c1d8e8) pc(0x7f1656d8265f)]
Aborted (core dumped)
I'm not sure how to get a better output of what exactly is causing the errors as it feels a bit cryptic.
Code crashes here
Pointer<wasm_extern_vec_t> exports = allocate<wasm_extern_vec_t>();
w.wasm_extern_vec_new_empty(exports);
w.wasm_instance_exports(instance, exports);
ffi glue code
typedef _c_wasm_instance_exports = ffi.Void Function(
ffi.Pointer<wasm_instance_t> arg0,
ffi.Pointer<wasm_extern_vec_t> out,
);
typedef _dart_wasm_instance_exports = void Function(
ffi.Pointer<wasm_instance_t> arg0,
ffi.Pointer<wasm_extern_vec_t> out,
);
void wasm_instance_exports(
ffi.Pointer<wasm_instance_t> arg0,
ffi.Pointer<wasm_extern_vec_t> out,
) {
_wasm_instance_exports ??= _dylib.lookupFunction<_c_wasm_instance_exports,
_dart_wasm_instance_exports>('wasm_instance_exports');
return _wasm_instance_exports(
arg0,
out,
);
}
So yeah, are there any resources i can refer to about investigating these crashes?
##edit##
The api is a C exported api from the rust wasmer project
exported header is
#ifndef WASM_API_EXTERN
#ifdef _WIN32
#define WASM_API_EXTERN __declspec(dllimport)
#else
#define WASM_API_EXTERN
#endif
#endif
WASM_API_EXTERN void wasm_instance_exports(const wasm_instance_t*, own wasm_extern_vec_t* out);
rust implementation is at
https://github.com/wasmerio/wasmer/blob/0a4a2c7d24d718e48eb9aa895292d3cbf950f7ed/lib/c-api/src/wasm_c_api/instance.rs#L178
more detailed code
Pointer<wasm_byte_vec_t> wat = allocate<wasm_byte_vec_t>() ;
Pointer<wasm_byte_vec_t> wasm_bytes = allocate<wasm_byte_vec_t>();
w.wasm_byte_vec_new(wat, code.length, Utf8.toUtf8(code).cast());
w.wat2wasm(wat, wasm_bytes);
var engine = w.wasm_engine_new();
var store = w.wasm_store_new(engine);
var module = w.wasm_module_new(store, wasm_bytes);
if (module == nullptr) {
print("> Error compiling module!\n");
return;
}
w.wasm_byte_vec_delete(wasm_bytes);
Pointer<wasm_extern_vec_t> imports = allocate<wasm_extern_vec_t>();
w.wasm_extern_vec_new_empty(imports);
var instance = w.wasm_instance_new(store, module, imports, nullptr);
if (instance != nullptr) {
print("> Error instantiating module %d!\n");
return ;
}
//
Pointer<wasm_extern_vec_t> exports = allocate<wasm_extern_vec_t>();
w.wasm_extern_vec_new_empty(exports);
w.wasm_instance_exports(instance, exports);
if (exports.ref.size == 0) {
print("> Error accessing exports!\n");
return;
}

How to set LLVM &AnalysisType::ID For Analysis Pass

I'm trying to create an analysis pass. My code is shown below. I'm using Adrian Sampson approach for building the .so file (https://www.cs.cornell.edu/~asampson/blog/llvm.html).
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "DataDependence.h"
#include "ControlDependence.h"
#include "llvm/IR/Module.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
using namespace llvm;
namespace {
struct SkeletonPass : public ModulePass {
static char ID;
SkeletonPass() : ModulePass(ID) {}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfoWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
// AU.addPreserved<AliasAnalysis>();
// AU.setPreservesCFG();
// AU.addRequired<PostDominatorTree>();
}
virtual bool runOnModule(Module &M);
};
bool SkeletonPass::runOnModule(Module &M) {
for (auto mi = M.begin(); mi != M.end(); ++mi) {
if (mi->isDeclaration())
continue;
// MemoryDependenceAnalysis &MDA = getAnalysis<MemoryDependenceAnalysis>(*mi);
PostDominatorTree &PDT = getAnalysis<PostDominatorTree>(*mi); //Error is Here
}
errs() << "Test:\n";
}
}
char SkeletonPass::ID = 0;
static RegisterPass<SkeletonPass> X("SkeletonPass", "Hello World Pass",
false /* Only looks at CFG */,
true /* Analysis Pass */);
The error I'm getting is below
In file included from /usr/local/include/llvm/Pass.h:388:0,
from /media/quentinmayo/storage/Research/LLVM Dev/llvm-pass-skeleton/skeleton/Skeleton.cpp:1:
/usr/local/include/llvm/PassAnalysisSupport.h: In instantiation of ‘AnalysisType& llvm::Pass::getAnalysis(llvm::Function&) [with AnalysisType = llvm::PostDominatorTree]’:
/media/quentinmayo/storage/Research/LLVM Dev/llvm-pass-skeleton/skeleton/Skeleton.cpp:34:71: required from here
/usr/local/include/llvm/PassAnalysisSupport.h:253:38: error: ‘ID’ is not a member of ‘llvm::PostDominatorTree’
return getAnalysisID<AnalysisType>(&AnalysisType::ID, F);
^
skeleton/CMakeFiles/SkeletonPass.dir/build.make:62: recipe for target 'skeleton/CMakeFiles/SkeletonPass.dir/Skeleton.cpp.o' failed
make[2]: *** [skeleton/CMakeFiles/SkeletonPass.dir/Skeleton.cpp.o] Error 1
CMakeFiles/Makefile2:85: recipe for target 'skeleton/CMakeFiles/SkeletonPass.dir/all' failed
make[1]: *** [skeleton/CMakeFiles/SkeletonPass.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
The error is saying I'm missing AnalysisType::ID. I would like to pass the AliasAnalysis pointer to another class for analysis. I'm confused what this AnalysisType::ID would be? Additionally, can someone explain the relationship between getAnalysisUsage and getAnalysis when creating pass for analysis? Understanding compiler theory doesn't really help me with working with LLVM.
http://llvm.org/docs/doxygen/html/classllvm_1_1Pass.html#ab78af013d3a11515403da8517f8f3d4a
I needed to call the class member getDomTree .
DominatorTree &DI = getAnalysis(*mi).getDomTree();
Advice for others: get friendly with the doxygen pages and reading header files. And if it comes to it, look into the source of your current LLVM build.
Also,AliasAnalysis is now AAResultsWrapperPass.

ROS custom message with sensor_msgs/Image issue with subscriber

I have a custom message -
sensor_msgs/Image im
float32 age
string name
I could successfully write a publisher for this message and it seem to run ok. However, I have an issue with the subscriber.
#include <ros/ros.h>
#include <custom_msg/MyString.h>
#include <custom_msg/MyImage.h>
#include <image_transport/image_transport.h>
#include <sensor_msgs/Image.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <cv_bridge/cv_bridge.h>
void custom_image_rcvd( const custom_msg::MyImage& msg )
{
ROS_INFO_STREAM( "msg::: Name:"<< msg.name << " Age:"<< msg.age );
cv::Mat im = cv_bridge::toCvShare( msg.im, "bgr8" )->image ;
cv::imshow("viewz", im );
cv::waitKey(30);
}
int main( int argc, char ** argv )
{
ros::init(argc, argv, "custom_subscriber");
ros::NodeHandle nh;
ros::Subscriber sub2 = nh.subscribe( "custom_image", 2, custom_image_rcvd );
ros::spin();
}
When I try to catkin_make this I get the following error.
/home/eeuser/ros_workspaces/HeloRosProject/src/custom_msg/subsc.cpp: In function ‘void custom_image_rcvd(const MyImage&)’:
/home/eeuser/ros_workspaces/HeloRosProject/src/custom_msg/subsc.cpp:22:57: error: no matching function for call to ‘toCvShare(const _im_type&, const char [5])’
/home/eeuser/ros_workspaces/HeloRosProject/src/custom_msg/subsc.cpp:22:57: note: candidates are:
/opt/ros/hydro/include/cv_bridge/cv_bridge.h:198:17: note: cv_bridge::CvImageConstPtr cv_bridge::toCvShare(const Image&, const boost::shared_ptr<const void>&, const string&)
/opt/ros/hydro/include/cv_bridge/cv_bridge.h:198:17: note: no known conversion for argument 2 from ‘const char [5]’ to ‘const boost::shared_ptr<const void>&’
/opt/ros/hydro/include/cv_bridge/cv_bridge.h:171:17: note: cv_bridge::CvImageConstPtr cv_bridge::toCvShare(const ImageConstPtr&, const string&)
/opt/ros/hydro/include/cv_bridge/cv_bridge.h:171:17: note: no known conversion for argument 1 from ‘const _im_type {aka const sensor_msgs::Image_<std::allocator<void> >}’ to ‘const ImageConstPtr& {aka const boost::shared_ptr<const sensor_msgs::Image_<std::allocator<void> > >&}’
make[2]: *** [custom_msg/CMakeFiles/subscribe.dir/subsc.cpp.o] Error 1
make[1]: *** [custom_msg/CMakeFiles/subscribe.dir/all] Error 2
make: *** [all] Error 2
Invoking "make" failed
What I can make out is that msg.im is of the type _im_type aka. sensor_msgs::Image_<ContainerAllocator>. I cannot seem to understand this part.
How can I retrieve my image correctly from this custom message?
You have to take a closer look on the signature of toCvShare. It can be read from the error message, that this function has two overloads:
cv_bridge::CvImageConstPtr cv_bridge::toCvShare(const Image&, const boost::shared_ptr<const void>&, const string&)
and
cv_bridge::CvImageConstPtr cv_bridge::toCvShare(const ImageConstPtr&, const string&)
So the function either expects an Image plus a pointer to some object (first case) or a ImageConstPtr (second case). You are, however, only passing a Image, so this matches neither of the two options.
If I understand the API documentation correctly, the second argument in the first case is expected to be a pointer to the message that contains the image. Try the following code:
void custom_image_rcvd(const custom_msg::MyImageConstPtr& msg)
{
ROS_INFO_STREAM("msg::: Name:" << msg->name << " Age:" << msg->age);
cv::Mat im = cv_bridge::toCvShare(msg->im, msg, "bgr8")->image;
cv::imshow("viewz", im);
cv::waitKey(30);
}
Note that I changed the call of toCvShare as well as the signature of the callback.

Building Unity App to iPad

I'm trying to build my simple app to run on the iPad. What my app is doing is trying to read from the on board pastebin which is having some data sent to it via a second app.
However, upon building the app on xcode I have the following linker errors:
Undefined symbols for architecture armv7: "_importString",
referenced from:
RegisterMonoModules() in RegisterMonoModules.o "_exportString", referenced from:
RegisterMonoModules() in RegisterMonoModules.o ld: symbol(s) not found for architecture armv7 clang: error: linker command failed with
exit code 1 (use -v to see invocation)
Now I know that it is looking at my import and export strings but nothing is ever started with a double underscore. Take a look at my dll file I wrote in XCode:
#define MakeStringCopy( _x_ ) ( _x_ != NULL && [_x_ isKindOfClass:[NSString class]] ) ? strdup( [_x_ UTF8String] ) : NULL
#define GetStringParam( _x_ ) ( _x_ != NULL ) ? [NSString stringWithUTF8String:_x_] : [NSString stringWithUTF8String:""]
//send clipboard to unity
extern "C" const char * importString()
{
NSString *result = [UIPasteboard generalPasteboard].string;
return MakeStringCopy(result);
}
//get clipboard from unity
extern "C" void exportString(const char * eString)
{
[UIPasteboard generalPasteboard].string = GetStringParam(eString);//#"the text to copy";
}
And the sister class I have in my Unity application:
[DllImport("__Internal")]
private static extern string _importString();
//retrieves the clipboard contents from xcode
public static string ImportString()
{
//Debug.Log ("import: "+_importString());
if( Application.platform == RuntimePlatform.IPhonePlayer )
{
return _importString();
}
else
{
return "";
}
}
[DllImport("__Internal")]
private static extern void _exportString(string exportData);
//passes string to xcode and xcode copies to clipboard
public static void ExportString(string exportData)
{
// Debug.Log ("export: "+exportData);
if( Application.platform == RuntimePlatform.IPhonePlayer )
{
_exportString(exportData);
}
}
I have stored the dll file in the following folder structor in Unity:
Assets -> Plugin -> iOS
But I'm at a loss as to how to fix my errors. Can anyone please help?
update
Based on a suggestion below I have ommited the underscore from both the import string and export string and I still have the same issues.

My lua script load .so library, how can I write the host program with Lua 5.2?

I searched and tried for days. The problem is this:
I wrote a script which load a shared library locker.so, it runs well with lua interpretor, but I can not write out the correct host program.
My lua script load_so.lua is very simple:
locker = require("locker")
print(type(locker))
for k, v in pairs(locker) do
print(k, v)
end
My host program is:
int main(int argc, const char *argv[])
{
lua_State * L = luaL_newstate();
luaL_openlibs(L);
if (luaL_dofile(L, "load_so.lua") != 0) {
fprintf(stderr, "luaL_dofile error: %s\n", lua_tostring(L, -1));
lua_pop(L, 1);
}
lua_close(L);
return 0;
}
When I run my host program, error print out:
luaL_dofile error: error loading module 'locker' from file './locker.so':
./locker.so: undefined symbol: lua_pushstring
And the locker.c:
static int elock_get(lua_State * L) {...}
static int elock_set(lua_State * L) {...}
static const struct luaL_Reg lockerlib[] = {
{"get", elock_get},
{"set", elock_set},
{NULL, NULL}
};
int luaopen_locker(lua_State *L)
{
//luaL_newlib(L, lockerlib);
//lua_pushvalue(L, -1);
//lua_setglobal(L, LOCKER_LIBNAME);
//set_info(L);
luaL_newlibtable(L, lockerlib);
luaL_setfuncs(L, lockerlib, 0);
return 1;
}
Most articles, books, questions shows how to do it in Lua 5.1, and yes, the program runs correctly in Lua 5.1. But how can I make it support Lua 5.2, and why?
P.S: I don't want to load the library in my C host program like luaL_requiref(L, "locker", luaopen_locker, 1), because I don't know which .so library will load in Lua script.
Thanks.
In Linux, if you're linking liblua.a statically into your main program, you need to use -Wl,-E when linking to export the Lua API symbols; this is how the standard command line interpreter is built.

Resources