I would like to know how to check if a preloaded module exists or not in Lua using C++.
My Code :
#include "lua.hpp"
bool isModuleAvailable(lua_State *L, std::string name)
{
//what should be here?
return false;
}
int main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_settop(L, 0);
luaL_dostring(L, "package.preload['A'] = function()\n"
"local a = {}\n"
"return a\n"
"end\n");
luaL_dostring(L, "package.preload['B'] = function()\n"
"local b = {}\n"
"return b\n"
"end\n");
if (isModuleAvailable(L, "A"))
std::cout << "Module Available" << '\n';
else
std::cout << "Module Not Available" << '\n';
if (isModuleAvailable(L, "B"))
std::cout << "Module Available" << '\n';
else
std::cout << "Module Not Available" << '\n';
if (isModuleAvailable(L, "C"))
std::cout << "Module Available" << '\n';
else
std::cout << "Module Not Available" << '\n';
lua_close(L);
}
The Result I get :
Module Not Available
Module Not Available
Module Not Available
The Result I want :
Module Available
Module Available
Module Not Available
How can I create isModuleAvailable() function so my code can work as expected?
Just check whether the field package.preload[name] is nil. I also renamed the function to isModulePreloaded because that's what is checks.
bool isModulePreloaded(lua_State *L, std::string const &name) {
lua_getglobal(L, "package");
lua_getfield(L, -1, "preload");
lua_getfield(L, -1, name.c_str());
bool is_preloaded = !lua_isnil(L, -1);
lua_pop(L, 3);
return is_preloaded;
}
Related
I might be missing something very easy but still i confronted this problem that i couldnt solve. I create a dll with these functions,
extern "C"{
__declspec(dllexport) void some();
__declspec(dllexport) void printer();
}
void printer()
{
printf("printing...\n");
}
i compile it using cmake
cmake .. -G "Visual Studio 15 2017" -A x64 -DBUILD_SHARED_LIBS=TRUE
cmake --build . --config Release
the i load it from my dllloader.cpp
int main() {
HINSTANCE hGetProcIDDLL = LoadLibrary("mydll.dll");
if (hGetProcIDDLL == NULL) {
std::cout << "cannot locate the .dll file" << std::endl;
} else {
std::cout << "it has been called" << std::endl;
}
if(GetProcAddress(hGetProcIDDLL, "printer") == NULL){
}else{
std::cout <<"not null" << std::endl;
}
std::cout << GetLastError() << " err" << std::endl;
getchar();
return 0;
}
So GetLastError returns 0 but nothing is printed, in the original file it is pretty much the same, the function is more that just a printf() call but the function gets loaded, how do we run it ? I know i might be missing something, just function does not execute. Any help is appreciated
typedef void(*my_dll_print)(); // function pointer to print method of dll
int main()
{
HINSTANCE hGetProcIDDLL = LoadLibrary("mydll.dll");
if (hGetProcIDDLL == nullptr)
std::cout << "cannot locate the .dll file" << std::endl;
else
std::cout << "it has been called" << std::endl;
my_dll_print print_method = reinterpret_cast<my_dll_print>(GetProcAddress(hGetProcIDDLL, "printer")); // Extract method address and create pointer
if (print_method == nullptr)
std::cout << "is null" << std::endl;
else
print_method(); // Call dll method
std::cout << GetLastError() << " err" << std::endl;
getchar();
return 0;
}
Try to use nullptr instead NULL to check pointer.
GetProcAdrress retrieves the address of an exported function or variable from the specified dynamic-link library! and makes no function call. You must first assign to function pointer then make call to pointed function!
I'm trying to familiarise myself with the OpenSSL Diffie Hellman features and, in doing so, I've tried to create a simple programme which will generate two sets of Diffie Hellman private and public keys and then derive the shared secret. I have followed the Diffie Hellman tutorial on the OpenSSL wiki and I am able to generate the keys, however I am unable to derive the shared secret. My C++ (Linux) code is as follows:
#include <iostream>
#include <openssl/dh.h>
#include <openssl/engine.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
int main(int argc, char** argv)
{
EVP_PKEY* params;
EVP_PKEY_CTX *kctx1, *kctx2, *dctx1, *dctx2;
unsigned char *skey1, *skey2;
size_t skeylen1, skeylen2;
EVP_PKEY *dh_1, *dh_2;
BIO* bio_out = NULL;
int result = 0;
ENGINE* eng;
BIO* fp = BIO_new_fp(stdout, BIO_NOCLOSE);
// Initalise Diffie Hellman PKEY for client 1
if(NULL == (dh_1 = EVP_PKEY_new())) {
std::cout << "error 1" << std::endl;
}
// Initalise Diffie Hellman PKEY for client 2
if(NULL == (dh_2 = EVP_PKEY_new())) {
std::cout << "error 2" << std::endl;
}
// Initalise Diffie Hellman parameter PKEY
if(NULL == (params = EVP_PKEY_new())) {
std::cout << "error 3" << std::endl;
}
// Set Diffie Hellman paramerers
if(1 != EVP_PKEY_set1_DH(params, DH_get_2048_256())) {
std::cout << "error 4" << std::endl;
}
// Initalise client 1 PKEY Context
if(!(kctx1 = EVP_PKEY_CTX_new(params, NULL))) {
std::cout << "error 5" << std::endl;
}
// Initalise client 2 PKEY Context
if(!(kctx2 = EVP_PKEY_CTX_new(params, NULL))) {
std::cout << "error 6" << std::endl;
}
if(!kctx1) {
std::cout << "error 7" << std::endl;
}
if(!kctx2) {
std::cout << "error 8" << std::endl;
}
// Initalise both contexts key generators
if(1 != EVP_PKEY_keygen_init(kctx1)) {
std::cout << "error 9" << std::endl;
}
if(1 != EVP_PKEY_keygen_init(kctx2)) {
std::cout << "error 10" << std::endl;
}
// Generate DH public and private keys for client 1
if(1 != EVP_PKEY_keygen(kctx1, &dh_1)) {
std::cout << "error 11" << std::endl;
}
// Generate DH public and private keys for client 2
if(1 != EVP_PKEY_keygen(kctx2, &dh_2)) {
std::cout << "error 12" << std::endl;
}
// EVP_PKEY_print_public(fp, dh_1, 3, NULL);
// EVP_PKEY_print_public(fp, dh_2, 3, NULL);
// Create key derivation context
if(NULL == (dctx1 = EVP_PKEY_CTX_new(dh_1, NULL))) {
std::cout << "error 13" << std::endl;
}
if(!dctx1) {
std::cout << "error 14" << std::endl;
}
// Initalise first key derivation context
if(1 != EVP_PKEY_derive_init(dctx1)) {
std::cout << "error 15" << std::endl;
}
if(1 != EVP_PKEY_check(dctx1)) {
std::cout << "error 16" << std::endl;
}
if(1 != EVP_PKEY_param_check(dctx1)) {
std::cout << "error 17" << std::endl;
}
// Set first key derivation context peer key to the second DH PKEY
if(1 != EVP_PKEY_derive_set_peer(dctx1, dh_2)) {
std::cout << "error 18" << std::endl;
}
if(1 != EVP_PKEY_public_check(dctx1)) {
std::cout << "error 19" << std::endl;
}
/* Determine buffer length */
if(EVP_PKEY_derive(dctx1, NULL, &skeylen1) <= 0) {
}
// Assign memory for shared key variable
skey1 = (unsigned char*)OPENSSL_malloc(skeylen1);
if(result = EVP_PKEY_derive(dctx1, skey1, &skeylen1) <= 0) {
std::cout << "Key: " << skey1 << std::endl;
for(int i = 0; i < skeylen1; i++) {
std::cout << std::hex << (unsigned int)skey1[i];
}
}
ERR_print_errors_fp(stdout);
std::cout << result << std::endl;
}
My main concerns are:
What do I need to do to derive the shared secret?
Do I need a new context for each key pair and key derivation?
Thanks!
EDIT:
I get the following errors and no shared key:
140690271102784:error:05079079:Diffie-Hellman routines:DH_check_ex:unable to check generator:../crypto/dh/dh_check.c:92:
140690271102784:error:05079076:Diffie-Hellman routines:DH_check_ex:check p not safe prime:../crypto/dh/dh_check.c:96:
140690271102784:error:0507B07B:Diffie-Hellman routines:DH_check_pub_key_ex:check pubkey too large:../crypto/dh/dh_check.c:190:
140690271102784:error:0507B07A:Diffie-Hellman routines:DH_check_pub_key_ex:check pubkey invalid:../crypto/dh/dh_check.c:192:
when I use
if(NULL == (dctx1 = EVP_PKEY_CTX_new(dh_1, NULL))) {
std::cout << "error 13" << std::endl;
}
and I get the following errors
error 16
error 19
Key: �ȭ��U
c0c8add7c4550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
139939742943040:error:060BA096:digital envelope routines:EVP_PKEY_check:operation not supported for this keytype:../crypto/evp/pmeth_gn.c:188:
139939742943040:error:0507C07D:Diffie-Hellman routines:dh_pkey_public_check:missing pubkey:../crypto/dh/dh_ameth.c:517:
139939742943040:error:05066064:Diffie-Hellman routines:compute_key:no private value:../crypto/dh/dh_key.c:183:
1
when I change "EVP_PKEY_CTX_new(dh_1, NULL)" to "EVP_PKEY_CTX_new(params, NULL)", like so:
if(NULL == (dctx1 = EVP_PKEY_CTX_new(params, NULL))) {
std::cout << "error 13" << std::endl;
}
The difference between these two variables is that "dh_1" stores a DH keypair, whereas "params" contains the DH parameters. It appears that the derivation context initalises to some extent with the latter, though it does not have a private and public key associated with it.
With the version of the code that you posted I got slightly different errors to you. I get the following output from your code (linked against OpenSSL 1.1.1):
error 16
error 17
140673674348352:error:060BA096:digital envelope routines:EVP_PKEY_check:operation not supported for this keytype:crypto/evp/pmeth_gn.c:187:
140673674348352:error:05079076:Diffie-Hellman routines:DH_check_ex:check p not safe prime:crypto/dh/dh_check.c:93:
0
The first "error 16" output is simply because OpenSSL does not currently support the EVP_PKEY_check() call for Diffie-Hellman keys. So this can be safely ignored.
The second "error 17" output (which is associated with the "check p not safe prime" error in the error queue) is more of an issue. This is because Diffie-Hellman keys come in two different varieties. By default OpenSSL uses PKCS#3 Diffie-Hellman keys. However it also supports X9.42 Diffie-Hellman keys. The function DH_get_2048_256() gives you a built-in set of parameters for X9.42 keys. However the function EVP_PKEY_set1_DH() expects the provided DH object to be a PKCS#3 key.
This actually looks like a bug in OpenSSL to me (EVP_PKEY_set1_DH() should really detect what type of key it is and do the right thing), so I have raised the following OpenSSL issue for this:
https://github.com/openssl/openssl/issues/10592
You can work around this by replacing the EVP_PKEY_set1_DH() call with one to EVP_PKEY_assign() instead and specify the type as EVP_PKEY_DHX as follows:
if(1 != EVP_PKEY_assign(params, EVP_PKEY_DHX, DH_get_2048_256())) {
std::cout << "error 4" << std::endl;
}
Alternatively you might just use PKCS#3 parameters instead.
Finally, the reason you get no shared secret derived is because you are only printing it if the EVP_PKEY_derive() call fails! It is actually succeeding!
I made the following changes to your code and it works for me:
--- derive.cpp 2019-12-09 11:11:15.493349734 +0000
+++ derive-new.cpp 2019-12-09 11:14:59.348715074 +0000
## -37,7 +37,7 ##
}
// Set Diffie Hellman paramerers
- if(1 != EVP_PKEY_set1_DH(params, DH_get_2048_256())) {
+ if(1 != EVP_PKEY_assign(params, EVP_PKEY_DHX, DH_get_2048_256())) {
std::cout << "error 4" << std::endl;
}
## -96,9 +96,11 ##
std::cout << "error 15" << std::endl;
}
+#if 0
if(1 != EVP_PKEY_check(dctx1)) {
std::cout << "error 16" << std::endl;
}
+#endif
if(1 != EVP_PKEY_param_check(dctx1)) {
std::cout << "error 17" << std::endl;
## -120,7 +122,7 ##
// Assign memory for shared key variable
skey1 = (unsigned char*)OPENSSL_malloc(skeylen1);
- if(result = EVP_PKEY_derive(dctx1, skey1, &skeylen1) <= 0) {
+ if((result = EVP_PKEY_derive(dctx1, skey1, &skeylen1)) > 0) {
std::cout << "Key: " << skey1 << std::endl;
for(int i = 0; i < skeylen1; i++) {
Above is Eliptic Curve Diffie and Hellman. A working example with OpenSSL 3 (none eliptic curve)
https://gist.github.com/digitalhuman/2a2b85d61672e4bf83596d41351723ba
Windows 10 x64, MSVC 2017, LuaJIT 2.0.5.
I searched the web, but answers didn't help.
Basically I'm trying to follow this manual, except that I had to place #include <LuaBridge.h> after Lua includes, because otherwise it doesn't work saying that the LuaBridge should go after Lua includes.
Hovewher, I get following error: PANIC: unprotected error in call to Lua API (attempt to call a nil value).
I have no idea why. If you need more info - just say what.
#include "stdafx.h"
#include <iostream>
#include <lua.hpp>
#include <LuaBridge/LuaBridge.h>
using namespace luabridge;
using namespace std;
int main()
{
lua_State* L = luaL_newstate();
luaL_dofile(L, "script.lua");
luaL_openlibs(L);
lua_pcall(L, 0, 0, 0);
LuaRef s = getGlobal(L, "testString");
LuaRef n = getGlobal(L, "number");
string luaString = s.cast<string>();
int answer = n.cast<int>();
cout << luaString << endl;
cout << "And here's our number:" << answer << endl;
system("pause");
return 0;
}
script.lua:
testString = "LuaBridge works!"
number = 42
The code in the tutorial is faulty. lua_pcall has nothing to call because luaL_dofile and luaL_openlibs don't push a function onto the stack, so it tries to call nil and returns 2 (the value of the macro LUA_ERRRUN).
I verified this by changing the code from the tutorial thus and compiling with g++. I didn't get a PANIC error, for whatever reason; maybe because it was using Lua 5.3:
#include <iostream>
extern "C" {
# include "lua.h"
# include "lauxlib.h"
# include "lualib.h"
}
#include <LuaBridge/LuaBridge.h>
using namespace luabridge;
int main() {
lua_State* L = luaL_newstate();
luaL_dofile(L, "script.lua");
std::cout << "type of value at top of stack: " << luaL_typename(L, -1) << std::endl;
luaL_openlibs(L);
std::cout << "type of value at top of stack: " << luaL_typename(L, -1) << std::endl;
std::cout << "result of pcall: " << lua_pcall(L, 0, 0, 0) << std::endl; // Print return value of lua_pcall. This prints 2.
LuaRef s = getGlobal(L, "testString");
LuaRef n = getGlobal(L, "number");
std::string luaString = s.cast<std::string>();
int answer = n.cast<int>();
std::cout << luaString << std::endl;
std::cout << "And here's our number: " << answer << std::endl;
}
As you noticed, the code is also faulty because the Lua headers have to be included before the LuaBridge header!
This question is related to #Henri_Menke's answer from this question : How to get preloaded module name in C++
I'm trying to override the require function with my own version so I can get the preloaded module name inside Lua script.
Here's my code:
#include "lua.hpp"
void main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_settop(L, 0);
luaL_dostring(L, "local require_original = require\n"
"function require(name, ...)\n"
"current_module = name\n"
"require_original(name, ...)\n"
"current_module = nil\n"
"end\n"); //if I comment out this chunk, it works fine
luaL_dostring(L, "package.preload['test'] = function ()\n"
"local test = {}\n"
"print('While loading:', current_module)\n"
"function test.update() print('Updated!') end\n"
"return test\n"
"end\n");
lua_getglobal(L, "require");
lua_pushstring(L, "test");
if (lua_pcall(L, 1, LUA_MULTRET, 0))
{
std::cout << "Error: " << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1);
}
int top = lua_gettop(L);
lua_getfield(L, -1, "update"); //crashes here
if (lua_isfunction(L, -1))
{
lua_pushnil(L);
if (lua_pcall(L, 1, LUA_MULTRET, 0))
{
std::cout << "Error: " << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1);
}
}
lua_close(L);
}
However, it crashes when calling lua_getfield(L, -1, "update");.
And it no longer crashes when I comment out the first chunk of Lua script(first luaL_dostring).
I don't understand why it crashes if I use my own version of require.
How can I fix this?
I forgot to return the module table from overridden require function. Sorry about that.
#include <iostream>
#include "lua.hpp"
int main() {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_settop(L, 0);
luaL_dostring(L, "local require_original = require\n"
"function require(name, ...)\n"
"current_module = name\n"
"local val = table.pack(require_original(name, ...))\n"
"current_module = nil\n"
"return table.unpack(val,1,val.n)\n"
"end\n"); //if I comment out this chunk, it works fine
luaL_dostring(L, "package.preload['test'] = function ()\n"
"local test = {}\n"
"print('While loading:', current_module)\n"
"function test.update() print('Updated!') end\n"
"return test\n"
"end\n");
lua_getglobal(L, "require");
lua_pushstring(L, "test");
if (lua_pcall(L, 1, LUA_MULTRET, 0))
{
std::cout << "Error: " << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1);
}
int top = lua_gettop(L);
lua_getfield(L, -1, "update"); //crashes here
if (lua_isfunction(L, -1))
{
lua_pushnil(L);
if (lua_pcall(L, 1, LUA_MULTRET, 0))
{
std::cout << "Error: " << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1);
}
}
lua_close(L);
}
$ clang++ -Wall -Wextra -Wpedantic -I /usr/include/lua5.2 test.cpp -llua5.2
test.cpp:28:9: warning: unused variable 'top' [-Wunused-variable]
int top = lua_gettop(L);
^
1 warning generated.
$ ./a.out
While loading: test
Updated!
I've got a threading problem that I've been trying to find an answer to on SO and Google, but with no luck.
Simply put I would want to create a thread that can execute a function that is using another function as a parameter (with its own arguments - see below).
I've followed these guides (https://www.justsoftwaresolutions.co.uk/threading/multithreading-in-c++0x-part-2-function-objects-and-arguments.html) on threading that work absolutely flawlessly, except for the above mentioned use case.
This is the specific line where I attempt to create the thread:
std::thread t(executeQuery, buildQuery(*_mVecHistIter, symbol));
And these are the nested functions definitions:
std::wstring database_con::buildQuery(vector<std::wstring> input, string symbol)
void database_con::executeQuery(wstring query)
And the error:
no instance of constructor "std::thread::thread" matches the argument
list
I could simply rebuild the functions so that buildQuery starts executeQuery. But I would want to separate the calls and ensure that as much as possible is done from the class "body" for readability and maintainability down the line.
Any kind of advice, pointers or ideas of where I can find more material on the subject would be appreciated! :)
I'm using MSVC 2015.
Edit:
#include "stdafx.h"
#include "database_con.h"
////////////////////////////////////////////////////////////////////////
// Show errors from the SQLHANDLE
void database_con::show_error(unsigned int handletype, const SQLHANDLE& handle)
{
SQLWCHAR sqlstate[1024];
SQLWCHAR message[1024];
if (SQL_SUCCESS == SQLGetDiagRec(handletype, handle, 1, sqlstate, NULL, message, 1024, NULL))
wcout << "Message: " << message << "\nSQLSTATE: " << sqlstate << endl;
}
std::wstring database_con::StringToWString(const std::string& s)
{
std::wstring temp(s.length(), L' ');
std::copy(s.begin(), s.end(), temp.begin());
return temp;
}
////////////////////////////////////////////////////////////////////////
// Builds the stored procedure query.
std::wstring database_con::buildQuery(vector<std::wstring> input, string symbol)
{
std::wstringstream builder;
builder << L"EXEC sp_addHistorical " << "#Symbol='" << L"" << StringToWString(symbol) << "'," <<
"#Date='" << (wstring)L"" << input.at(0) << "'," <<
"#Open=" << (wstring)L"" << input.at(1) << "," <<
"#Close=" << (wstring)L"" << input.at(2) << "," <<
"#MaxPrice=" << (wstring)L"" << input.at(3) << "," <<
"#MinPrice=" << (wstring)L"" << input.at(4) << "," <<
"#Volume=" << (wstring)L"" << input.at(5) << ";";
return builder.str();
}
void database_con::executeQuery(wstring query) {
if (SQL_SUCCESS != SQLExecDirectW(stmt, const_cast<SQLWCHAR*>(query.c_str()), SQL_NTS)) {
std::cout << "Execute error " << std::endl;
show_error(SQL_HANDLE_STMT, stmt);
std::wcout << L"Unsuccessful Query: " << query << std::endl;
}
// Close Cursor before next iteration starts:
SQLRETURN closeCursRet = SQLFreeStmt(stmt, SQL_CLOSE);
if (!SQL_SUCCEEDED(closeCursRet))
{
show_error(SQL_HANDLE_STMT, stmt);
// maybe add some handling for the case that closing failed.
}
}
////////////////////////////////////////////////////////////////////////
// Constructs a database connector object with the historical data and its symbol
database_con::database_con(std::vector<std::vector<std::wstring>> historical, string symbol){
/*
Set up the handlers
*/
/* Allocate an environment handle */
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
/* We want ODBC 3 support */
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
/* Allocate a connection handle */
SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
/* Connect to the DSN */
SQLDriverConnectW(dbc, NULL, L"DRIVER={SQL Server};SERVER=ERA-PC-STUART\\JBK_DB;DATABASE=master;UID=geo;PWD=kalle123;", SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);
/* Check for success */
if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt))
{
show_error(SQL_HANDLE_DBC, dbc);
std::cout << "Failed to connect";
}
std::cout << "Building and executing the query" << std::endl;
for (_mVecHistIter = historical.begin();
_mVecHistIter != historical.end();
_mVecHistIter+5) {
std::thread t(&database_con::executeQuery, *this, buildQuery(*_mVecHistIter, symbol));
std::thread t2(&database_con::executeQuery, *this, buildQuery(*_mVecHistIter, symbol));
std::thread t3(&database_con::executeQuery, *this, buildQuery(*_mVecHistIter, symbol));
std::thread t4(&database_con::executeQuery, *this, buildQuery(*_mVecHistIter, symbol));
std::thread t5(&database_con::executeQuery, *this, buildQuery(*_mVecHistIter, symbol));
t.join();
t2.join();
t3.join();
t4.join();
t5.join();
//executeQuery(buildQuery(*_mVecHistIter, symbol));
}
/*_mSymbol = symbol;
std::wstringstream stream(StringToWString(historical));
std::wstring line;
int row = 0;
while (std::getline(stream, line)) {
if (row > 0) {
vector<wstring> vHistorical = parseData(L"" + line, ',');
std::wstring SQL = buildQuery(vHistorical, _mSymbol);
if (SQL_SUCCESS != SQLExecDirectW(stmt, const_cast<SQLWCHAR*>(SQL.c_str()), SQL_NTS)) {
std::cout << "Execute error " << std::endl;
show_error(SQL_HANDLE_STMT, stmt);
std::wcout << L"Unsuccessful Query: " << SQL << std::endl;
}
// Close Cursor before next iteration starts:
SQLRETURN closeCursRet = SQLFreeStmt(stmt, SQL_CLOSE);
if (!SQL_SUCCEEDED(closeCursRet))
{
show_error(SQL_HANDLE_STMT, stmt);
// maybe add some handling for the case that closing failed.
}
}
row++;
}*/
std::cout << "Query " << _mSymbol << " ready" << std::endl;
}
database_con::~database_con() {
std::cout << "The database object has been deleted" << std::endl;
}
OK, I probably misunderstood the question. You don't want create a thread using a function, having one of its arguments another function. But rather create a thread using a function and having its parameter computed by another function. There is nothing particular about that. You probably just forget to add & operator to take an address of the function.
std::thread t(&executeQuery, buildQuery(*_mVecHistIter, symbol));
^-- note the &
EDIT
So, you forget to mention that database_con is a class. In order to use class member function as param for function acception pointer to function as parameter (in your case std::thread::thread) you have to use fully qualified name with operand & (&database_con::executeQuery). However, since that is non static member function, it will require its first argument pointer to instance of such object (google std::thread non-static member function).
std::thread t(&database_con::executeQuery, this, buildQuery(*_mVecHistIter, symbol));
Previous answer
Did you considered using std::function?
#include <functional>
#include <thread>
int foo(int arg1, int arg2)
{
return arg1 + arg2;
}
void bar(std::function<int(int, int)> fnc, int arg1, int arg2)
{
fnc(arg1, arg2);
}
int main()
{
std::thread thr{&bar, &foo, 1, 2};
}