I have this simple program which i make into dll in Visual C++ 2008 Express:
#include <lua52/lua.h>
#include <lua52/lualib.h>
#include <lua52/lauxlib.h>
#pragma comment(lib,"lua52.lib")
#include <stdio.h>
int needless(lua_State *L)
{
printf("bullshit\n");
return 0;
}
static const struct luaL_Reg noise[] = {
{"needless",needless},
{NULL,NULL}
};
__declspec(dllexport) int __cdecl luaopen_noise(lua_State *L)
{
luaL_newlib(L, noise);
return 1;
}
when I link the resulting dll with "import noise" in lua5.2 interpreter, I get that "multiple lua VMs detected" for reason that eludes me. What should I do to fix make it work?
Lua libraries written in C should not include a copy of the Lua core library.
I don't know Visual C+ but this line is probably the culprit:
#pragma comment(lib,"lua52.lib")
Related
I have a shared library linked to an executable for which I would like to have code coverage instrumentation using custom _sanitizer_cov_trace_pc* functions.
library.cc
#include <stdio.h>
void so_function() {
printf("SO function.");
}
callbacks.cc
#include <stdint.h>
#include <stdio.h>
#include <sanitizer/coverage_interface.h>
extern "C" void __sanitizer_cov_trace_pc_guard_init(uint32_t *start,
uint32_t *stop) {
static uint64_t N;
if (start == stop || *start) return;
printf("INIT: %p %p\n", start, stop);
for (uint32_t *x = start; x < stop; x++)
*x = ++N;
}
extern "C" void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
if (!*guard) return;
void *PC = __builtin_return_address(0);
char PcDescr[1024];
__sanitizer_symbolize_pc(PC, "%p %F %L", PcDescr, sizeof(PcDescr));
printf("guard: %p %x PC %s\n", guard, *guard, PcDescr);
}
main.cc
#include <stdio.h>
void so_function();
int main(int argc, char **argv) {
so_function();
}
I compiled the library using clang's -fsanitize-coverage=trace-pc-guard into position-independent code (-fPIC) and then I created the shared library using both the resulted object file and callbacks.cc using -fsanitize=address.
I compiled main.cc and linked it with the shared library but it seems like these 2 custom __sanitizer_cov_trace_pc_guard* functions don't get called.
I would like have code coverage instrumentation using these 2 functions only for the shared library, and not for the main executable.
I am trying to learn how to use the Xerces-c-3.1.4 DLL. I downloaded the source and built the DLL using the xerces-all.sln in VS Studio Express 2015.
I have written a very simple VCL app (a button on a form). This yields three linker errors:
Unresolved external 'xercesc_3_1::XMLPlatformUtils::Terminate()
Unresolved external 'xercesc_3_1::XMLUni::fgXercescDefaultLocale
Unresolved external 'xercesc_3_1::XMLPlatformUtils::Initialize()
The possible causes that occur to me include:
I did something wrong when building the DLL
Don't I need a .DEF file to deal with VC++ name mangling? None in the .sln provided, though.
Don't I need to call GetProcAddress for any DLL functions I use? But where can I find templates for all of the functions in the DLL?
Here's the code for my test app:
#ifndef MainFrmH
#define MainFrmH
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>
XERCES_CPP_NAMESPACE_USE
class TMainForm : public TForm
{
__published: // IDE-managed Components
TButton *InitButton;
void __fastcall InitButtonClick(TObject *Sender);
private: // User declarations
HINSTANCE hXercesLib;
public: // User declarations
__fastcall TMainForm(TComponent* Owner);
__fastcall ~TMainForm();
};
extern PACKAGE TMainForm *MainForm;
#endif
#include <vcl.h>
#include <iostream>
#pragma hdrstop
#include "MainFrm.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
using namespace xercesc;
__fastcall TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
hXercesLib = NULL;
} // ctor
__fastcall TMainForm::~TMainForm()
{
if (hXercesLib)
{
XMLPlatformUtils::Terminate();
FreeLibrary(hXercesLib);
hXercesLib = NULL;
}
} // dtor
void __fastcall TMainForm::InitButtonClick(TObject *Sender)
{
if (!hXercesLib)
{
hXercesLib = LoadLibrary("xerces-c_3_1.dll");
try
{
XMLPlatformUtils::Initialize();
ShowMessage("XMLPlatformUtils::Initialize succeeded");
}
catch (Exception& e)
{
FreeLibrary(hXercesLib);
hXercesLib = NULL;
ShowMessage(e.Message);
}
}
}
You can use GetProcAddress() but it is more work for your code to setup. You can use C++Builder's command-line tdump.exe tool to get a list of the DLL's exported function names.
You can alternatively use C++Builder's command-line implib.exe tool, with or without a .def file, to create a static import .lib file for the DLL, and then add that .lib file to your project.
I've seen quite a numerous amount of examples that go over creating functions passes (e.g. Brandon Holt and Adrian Sampson), but I am curious as to the difficulty in creating a module pass to do these very similar problems. I've tried to implement a module pass to display the global variable names using this example and llvm source code to understand how you have to iterate through members.
I am using a source compiled version of LLVM, and using the example from the above links to add the pass, and then running:
$ clang -Xclang -load -Xclang build/Skeleton/libSkeletonPass.so something.c
Which then returns this gibberish. However, if I implement a functionPass and just use Auto to determine the type to be initialized it's very straight forward and works. Am I just going about printing the global variables the wrong way?
This is a pastebin of the error output from the terminal. link
Skeleton.cpp
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/IR/LLVMContext.h"
using namespace llvm;
namespace {
// Helper method for converting the name of a LLVM type to a string
static std::string LLVMTypeAsString(const Type *T) {
std::string TypeName;
raw_string_ostream N(TypeName);
T->print(N);
return N.str();
}
struct SkeletonPass : public ModulePass {
static char ID;
SkeletonPass() : ModulePass(ID) {}
virtual bool runOnModule(Module &M) {
for (Module::const_global_iterator GI = M.global_begin(),
GE = M.global_end(); GI != GE; ++GI) {
errs() << "Found global named: " << GI->getName()
<< "\tType: " << LLVMTypeAsString(GI->getType()) << "!\n";
}
return false;
}
};
}
char SkeletonPass::ID = 0;
// Automatically enable the pass.
// http://adriansampson.net/blog/clangpass.html
static void registerSkeletonPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
PM.add(new SkeletonPass());
}
static RegisterStandardPasses
RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible,
registerSkeletonPass);
something.c
int value0 = 5;
int main(int argc, char const *argv[])
{
int value = 4;
value += 1;
return 0;
}
I was able to figure this out after some extensive github searching. Here is the answer from which I was following a tutorial to help others who may be curious how to implement a Module Pass.
I want to make a custom vapi file, I have the basic stuff but I obviously miss something and I can't find anywhere how to do this properly. My main goal is to create a torent app, using libtorrent, and create the GUI (the frontend?) with vala and gtk.
I have a c_func_head.h:
#ifndef WHATEVER_H_INCLUDED
#define WHATEVER_H_INCLUDED
int add(int a, int b);
#endif
c_functions.c:
#include <stdio.h>
#include <stdlib.h>
#include "c_func_head.h"
int add(int a, int b){
printf("Adding numbers in c...\n");
return a+b;
}
vala_p.vapi:
[CCode (cheader_filename = "c_func_head.h")]
namespace MyFunc {
[CCode (cname = "add")]
public int add (int a, int b);
}
and finally vala_program.vala:
//extern int add(int a, int b);
using MyFunc;
void main(){
stdout.printf("Calling a c function...\n");
//stdout.printf("The sum is: %d\n", add2number(2, 2));
int sum = add(2, 2);
stdout.printf("The sum is: %d\n", sum);
}
As you can see I used an extern too, it worked with it but I want to use vapi files.
I compiled with (everything is in the same folder):
valac vala_program.vala --vapidir=vala_p.vapi -o mustrun
and the error is:
The namespace name `MyFunc' could not be found using MyFunc;
One more thing. Is it possible to make bindings for libtorrent? It uses c++ and I gues I have to use c++ too.
You can't make Vala bindings of C++ code. Only C. There a a guide to writing legacy bindings and a binding for Transmission, which is C-based.
As for the specific error you have, you want to call valac vala_program.vala vala_p.vapi if the library (i.e., header files) are the the same directory or valac vala_program.vala --pkg vala_p --vapidir=/path/to/directory/containing/vapi.
I decided to add scripting with Lua. I've downloaded and compiled interpreter. It works fine, but when I want to use any functions from os.* or string.* libs, it says, that "attemt to index global 'os' (a nil value)"
Here is my code and should work, but it does not:
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
extern "C" {
#include "..\liblua\lua.h"
#include "..\liblua\lualib.h"
#include "..\liblua\lauxlib.h"
}
int main(int argc, TCHAR* argv[])
{
lua_State *LuaVM = luaL_newstate();
lua_pushcfunction(LuaVM,luaopen_base);
lua_call(LuaVM,0,0);
lua_pushcfunction(LuaVM,luaopen_math);
lua_call(LuaVM,0,0);
lua_pushcfunction(LuaVM,luaopen_string);
lua_call(LuaVM,0,0);
lua_pushcfunction(LuaVM,luaopen_table);
lua_call(LuaVM,0,0);
int error;
lua_pushstring(LuaVM,"Ver 0.525.5");
lua_setglobal(LuaVM,"Version");
while (true)
{
string strCode;
getline(cin,strCode);
error = luaL_loadbuffer(LuaVM,strCode.c_str(),strCode.length(),"") ||
lua_pcall(LuaVM,0,0,0);
if (error)
{
cout<< lua_tostring(LuaVM,-1)<<endl;
lua_pop(LuaVM,1);
}
}
lua_close(LuaVM);
return 0;
}
What's wrong with it?
In Lua 5.2 the standard luaopen_* functions do not set the corresponding global variables.
Why not copy and adapt the code in linit.c or just call luaL_openlibs?
Otherwise, do what they do: call luaL_requiref for each luaopen_* function.
See http://www.lua.org/source/5.2/linit.c.html#luaL_openlibs.