I need to use cygwin compiled dll from visual studio C++ or Code:blocks MinGW.
I tried use this simple example
#include <stdio.h>
int MyFunc()
{
printf("Printed from cygwin dll");
return 0;
}
And this makefile
obj = mydll.o
ALLLIBS = \
mydll.a \
mydll.dll
all: $(ALLLIBS)
mydll.a: $(obj)
$(LINK.a)
mydll.dll: $(obj)
$(cygTest.dll)
cygTest.dll = gcc -shared -o cygTest.dll \
-Wl,--out-implib \
-Wl,--export-all-symbols \
-Wl,--enable-auto-import \
-Wl,--whole-archive $(obj) \
-Wl,--no-whole-archive
mydll.a = ar $(ARFLAGS) $# $%
I am trying to call the final dll here.
#include <windows.h>
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
typedef int(*FnP_MyFunc)();
typedef void(*FnP_CYGWIN_DLL_INIT)();
int main()
{
FnP_MyFunc fnMyFunc;
HMODULE hLib, hGetCygwinIDDLL = LoadLibrary(TEXT("C:\\cygwin64\\bin\\cygwin1.dll"));
if (hGetCygwinIDDLL)
{
FnP_CYGWIN_DLL_INIT init = (FnP_CYGWIN_DLL_INIT)GetProcAddress(hGetCygwinIDDLL, "cygwin_dll_init");
init();
std::cout << "init complete " << endl;
}
int a;
hLib = LoadLibrary(TEXT("C:\\cygwin64\\home\\azatyan\\TestDynamicLink\\cygTest.dll"));
if (hLib)
{
std::cout << "From wrapper dll " << std::endl;
fnMyFunc = (FnP_MyFunc)GetProcAddress(hLib, "MyFunc");
a = fnMyFunc();
cout << a;
}
FreeLibrary(hGetCygwinIDDLL);
FreeLibrary(hLib);
return 0;
}
And it just hangs when it reaches to my MyFunc function. Or exits with code 1536..
Can anybody help me, what am I doing wrong?
UPDATE: I have tried the same without printf() function, worked ok, returned expected value, this means that the problem is in dependency libraries, but still I don't know haw I can add all dependency libraries..
Related
I tried to use the following code to output files in current directory
#include <filesystem>
#include <iostream>
using namespace std::filesystem;
int main() {
for (directory_iterator next("."), end; next != end; ++next) {
std::cout << next->path() << std::endl;
}
return 0;
}
the compile command is a simple g++ demo.cpp -o demo.exe, the path to g++ is C:\msys64\ucrt64\bin\g++.exe.
It worked properly when i ran it in bash (msys2),
$ ./demo.exe
".\\.clangd"
".\\.vscode"
".\\demo.cpp"
".\\demo.exe"
but when i did the same thing in powershell or cmd, it output nothing.
PS C:\Users\cnjawi> .\demo.exe
PS C:\Users\cnjawi>
The following code could run just fine in powershell and cmd.
#include <filesystem>
#include <iostream>
using namespace std::filesystem;
int main() {
std::cout << "test\n";
return 0;
}
However, if i add the original code, the issue occurs, even the "test" couldn't be output.
#include <filesystem>
#include <iostream>
using namespace std::filesystem;
int main() {
std::cout << "test\n";
for (directory_iterator next("."), end; next != end; ++next) {
std::cout << next->path() << std::endl;
}
return 0;
}
Thanks to HolyBlackCat's comment. When i double-clicked this program, Windows prompted The procedure entry point ~ could not be located, which gave the key info -- the program doesn't actually work in powershell due to some missing DLLs, rather than working but not outputting.
However, a collapsed program does not issue warnings in powershell, which made it appear to have worked "normally".
The simplest way to solve it is using the static library. For this instance, use g++ -c demo.cpp to generate demo.o and then g++ -static demo.o /ucrt64/lib/libstdc++fs.a -o demo.exe(in bash).
I have a project with the following structure:
Item.cpp
Item.h
main.cpp
Makefile
The following source code is in the Item.h file:
class Item {
public:
Item();
~Item();
};
The following source code is in the Item.cpp file:
#include <iostream>
#include "Item.h"
Item::Item() {
std::cout << "Item created..." << std::endl;
}
Item::~Item() {
std::cout << "Item destroyed..." << std::endl;
}
The following source code is the content of the main.cpp file:
#include "Item.h"
#include <iostream>
int main() {
std::cout << "Initialize program..." << std::endl;
Item item_1();
std::cout << "Hello world!" << std::endl;
return 0;
}
And finally, the following source code is the Makefile file:
CXX = g++
all: main item
$(CXX) -o sales.o main.o Item.o
main:
$(CXX) -c main.cpp
item:
$(CXX) -c Item.cpp
clean:
rm -rf *.o
When I run the make command and then I run the compiled code with the command ./sales.o, I get the following output:
Initialize program...
Hello world!
Why is the output of the constructor method of the class Item not printed in the console? I found in some web pages that you can compile the source codes in steps and then you can link it with the -o option when using g++ but it does not work in this case. How can I compile this source codes step by step and then link it in the Makefile?
I'm surely you ignored this warning :
warning: empty parentheses were disambiguated as a function declaration [-Wvexing-parse]
#include "Item.h"
#include <iostream>
int main() {
std::cout << "Initialize program..." << std::endl;
Item item_1;
std::cout << "Hello world!" << std::endl;
return 0;
}
just remove parentheses it will be work
test : https://godbolt.org/z/KrdrhvsrW
I have a sample file like so, lets call it dnn_mmod_face_detection_ex.cpp
#include <iostream>
#include <dlib/dnn.h>
#include <dlib/data_io.h>
#include <dlib/image_processing.h>
#include <dlib/gui_widgets.h>
using namespace std;
using namespace dlib;
// ----------------------------------------------------------------------------------------
template <long num_filters, typename SUBNET> using con5d = con<num_filters,5,5,2,2,SUBNET>;
template <long num_filters, typename SUBNET> using con5 = con<num_filters,5,5,1,1,SUBNET>;
template <typename SUBNET> using downsampler = relu<affine<con5d<32, relu<affine<con5d<32, relu<affine<con5d<16,SUBNET>>>>>>>>>;
template <typename SUBNET> using rcon5 = relu<affine<con5<45,SUBNET>>>;
using net_type = loss_mmod<con<1,9,9,1,1,rcon5<rcon5<rcon5<downsampler<input_rgb_image_pyramid<pyramid_down<6>>>>>>>>;
// ----------------------------------------------------------------------------------------
int main(int argc, char** argv) try
{
if (argc == 1)
{
cout << "Call this program like this:" << endl;
cout << "./dnn_mmod_face_detection_ex mmod_human_face_detector.dat faces/*.jpg" << endl;
cout << "\nYou can get the mmod_human_face_detector.dat file from:\n";
cout << "http://dlib.net/files/mmod_human_face_detector.dat.bz2" << endl;
return 0;
}
net_type net;
deserialize(argv[1]) >> net;
image_window win;
for (int i = 2; i < argc; ++i)
{
matrix<rgb_pixel> img;
load_image(img, argv[i]);
// Upsampling the image will allow us to detect smaller faces but will cause the
// program to use more RAM and run longer.
while(img.size() < 1800*1800)
pyramid_up(img);
// Note that you can process a bunch of images in a std::vector at once and it runs
// much faster, since this will form mini-batches of images and therefore get
// better parallelism out of your GPU hardware. However, all the images must be
// the same size. To avoid this requirement on images being the same size we
// process them individually in this example.
auto dets = net(img);
win.clear_overlay();
win.set_image(img);
for (auto&& d : dets)
win.add_overlay(d);
cout << "Hit enter to process the next image." << endl;
cin.get();
}
}
catch(std::exception& e)
{
cout << e.what() << endl;
}
I have a Makefile like so
CC=g++
CFLAGS=-c -Wall -std=c++11 -v
LDFLAGS=-L/usr/local/cuda/lib64 -ldlib -lcudnn -lpthread -ldl -lrt -lX11 -lcublas -lcudnn -lcurand -lcusolver -lstdc++ -lm -lgcc_s -lc -lxcb -lXau -lXdmcp
SOURCES=dnn_mmod_face_detection_ex.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=dnn_mmod_face_detection_ex
INCLUDE=
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $(INCLUDE) $< -o $#
But I get undefined references to almost every dlib library. ie
dnn_mmod_face_detection_ex.cpp:(.text+0x267): undefined reference to `dlib::image_window::image_window()'
dnn_mmod_face_detection_ex.cpp:(.text._ZNK4dlib8gpu_data4hostEv[_ZNK4dlib8gpu_data4hostEv]+0x14): undefined reference to `dlib::gpu_data::copy_to_host() const'
dnn_mmod_face_detection_ex.cpp:(.text._ZN4dlib16resizable_tensorC2Ev[_ZN4dlib16resizable_tensorC5Ev]+0x31): undefined reference to `dlib::cuda::tensor_descriptor::tensor_descriptor()'
I know the following
This same example is compiled and is runs inside the /dlib/build/test... directory (dlib-19.9)
Those LDFLAGS I obtained by issuing the command ldd /dlib/build/test.../dnn_mmod_face_detection_ex
What is the right way to figure out what libraries are missing? I tried tracing the Cmake file(s) that dlib provided but it is more complicated than a particle accelerator.
It was a simple mistake of misplacing the LDFLAGS. It works when placed at the end like so
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) -o $# $(LDFLAGS)
I have next some project:
main.cpp
#include <iostream>
#include <cstddef>
#include <dlfcn.h>
int main()
{
void* handle = dlopen("./shared_libs/libshared.so", RTLD_LAZY);
if (NULL == handle)
{
std::cerr << "Cannot open library: " << dlerror() << '\n';
return -1;
}
typedef int (*foo_t)(const std::size_t);
foo_t foo = reinterpret_cast<foo_t>(dlsym(handle, "foo"));
const char* dlsym_error = dlerror();
if (dlsym_error)
{
std::cerr << "Cannot load symbol 'foo': " << dlsym_error << '\n';
dlclose(handle);
return -2;
}
std::cout << "call foo" << std::endl;
foo(10);
dlclose(handle);
return 0;
}
shared.cpp:
#include <cstddef>
#include <iostream>
extern "C"
{
int foo(const std::size_t size)
{
int b = size / size;
int* a = new int[size];
std::cout << "leaky code here" << std::endl;
}
}
and Makefile:
all:
g++ -fPIC -g -c shared.cpp
g++ -shared -o shared_libs/libshared.so -g shared.o
g++ -L shared_libs/ -g main.cpp -ldl
I use tcmalloc for debug this test program, which load dynamically libshared.so:foo and execute it.run command:
LD_PRELOAD=/usr/local/lib/libtcmalloc.so HEAPCHECK=normal ./a.out
The 1 largest leaks:
Using local file ./a.out.
Leak of 40 bytes in 1 objects allocated from:
# 7fe3460bd9ba 0x00007fe3460bd9ba
# 400b43 main
# 7fe346c33ec5 __libc_start_main
# 400999 _start
# 0 _init
Why I get address 0x00007fe3460bd9ba instead of line in foo function?
please help
P.s. I tried to use gdb with LD_PRELOAD=.../tcmalloc.so, but I get:
"Someone is ptrace()ing us; will turn itself off Turning perftools heap leak checking off"
Try removing dlclose call.
It's known issue that heap checker & profilers can't handle unloaded
shared objects.
Hey this is more of a question, i want to know if it is possible to modify code through GUI asking because i was asked to see if i could create a GUI where the user can change certain attributes. i.e an exmaple is below
start %= -(status)
> lexeme[elementV]
> -(lexeme[elementF])
> +(inboundGroup);
Above is part of my code which is Boost SPIRIT which parses Strings so for example would it be possible to change the + to a * or - etc
+ = One
- = optional
* = multiple
Do you think it would be possible to change that through a GUI i think it could be just not sure on how to do it?
Any help i will be very grateful
Thanks Shamari
Everything is possible in programming ;-)
For dynamic modification of a program during execution, there are several solutions :
Use a dynamic language like LUA
Use a plugin system with dynamic loading
Since you require C++ and Boost Spirit, I think the best solution is to generate a plugin on the fly and load it afterwards.
Your program will generate code, compile it into a shared library (.so) and then load and execute it. (Some people will find that dirty. It's insecure also. But it's simple and it works.)
Here is an exemple for linux : plugin.h :
#ifndef PLUGIN_H__
#define PLUGIN_H__
#ifdef __cplusplus
extern "C" {
#endif
int process();
typedef int (*plugin_process_fn_ptr)();
#ifdef __cplusplus
}
#endif
#endif // PLUGIN_H__
Note that we must use extern C or else, C++ name mangling will make it difficult to import symbols.
plugin.cpp :
#include "plugin.h"
#include <iostream>
using namespace std;
int process()
{
int return_value = 0;
#include "plugin_content.inc.cpp"
return return_value;
}
Note that I use a hack here, the code will be included from another file, "plugin_content.inc.cpp". The code from user will be put inside.
a script to build the plugin, "build_plugin.sh" :
#! /bin/sh
g++ -c -Wall -fPIC plugin.cpp -o plugin.o
gcc -shared -o libplugin.so plugin.o
Now the calling program, main.cpp :
#include <iostream>
#include <fstream> // to open files
#include <dlfcn.h> // C lib to load dynamic libs
#include "plugin.h"
using namespace std;
// load the plugin and call the process() function fom it
static int process_via_plugin()
{
int return_value = -1;
void *lib_handle(NULL);
char *error(NULL);
char *plugin_lib = "./libplugin.so";
lib_handle = dlopen(plugin_lib, RTLD_LAZY);
if (!lib_handle)
{
cerr << "Error loading lib " << plugin_lib << " : " << dlerror() << endl;
exit(1);
}
char *plugin_fn = "process";
plugin_process_fn_ptr fn = (plugin_process_fn_ptr)dlsym(lib_handle, plugin_fn);
error = dlerror();
if (error)
{
cerr << "Error finding lib " << plugin_fn << " : " << error << endl;
exit(1);
}
// call the function loaded from lib
return_value = (*fn)();
dlclose(lib_handle);
lib_handle = NULL; // useless but for good habits ^^
return return_value;
}
// build or rebuild the plugin,
// we must call it when we change the plugin code code
static int build_plugin(string code)
{
{
char *plugin_code_file = "plugin_content.inc.cpp";
ofstream plugin_code(plugin_code_file, ios::out);
plugin_code << code << endl;
}
system("build_plugin.sh");
return 0;
}
// our program
int main(int argc, char *argv[])
{
cout << "Hello World !" << endl;
string code = ""
"cout << \"Hello from plugin !\" << endl;"
"";
// build a first version of the plugin and call it
build_plugin(code);
process_via_plugin();
// now we modify the code (use a GUI here)
code = ""
"cout << \"Hello from plugin, updated !\" << endl;"
"";
// rebuild the plugin and call it again
build_plugin(code);
process_via_plugin();
// do it again as much as you want.
return 0;
}
Now, build your program :
g++ -Wall -rdynamic -ldl main.cpp
and execute it :
a.out
and you get :
Hello World !
Hello from plugin !
Hello from plugin, updated !
The code I give you is very basic. For example, we should check if the compilation of the plugin is successful and report errors to the user. Now it's up to you to add more stuff.