I want to create a C++ program that loads a dll(a.dll). It should run in
combination with wine in Linux. In the dll a function foo will be called
which takes two strings and an integer. foo returns an integer. The dll
is located in the same directory as the exe. Unfortunately the dll file
is not found and I don't know why. I have also tried "./a.dll" under
Linux. Can anyone give me some advice on this?
#include <iostream>
#include <string>
#include "windows.h"
#include <tchar.h>
typedef int(*func_ptr)(std::string, std::string, int);
int main()
{
func_ptr function1 = NULL;
HMODULE hGetProcIDDLL = LoadLibrary(L"a.dll");
if (hGetProcIDDLL != NULL)
{
std::cout << "Found!";
}
else
{
std::cout << "File not found!";
return 0;
}
function1 = (func_ptr)GetProcAddress(hGetProcIDDLL, "foo");
if (function1 != NULL)
{
std::cout << function1("input-file.txt","output-file.txt",0);
}
else
{
std::cout << "Function not found";
}
FreeLibrary(hGetProcIDDLL);
std::cin.get();
return(0);
}
Related
I have two programs. The following code is an example I came up with to understand the basics before implementing the method into my main program. The child process is not editable and is an executable (as I do not have access to the source code for my main program).
The code for the child process code for my example:
#include <iostream>
#include <string>
using namespace std;
bool is_number(const std::string& s)
{
string::const_iterator it = s.begin();
while (it != s.end() && std::isdigit(*it)) ++it;
return !s.empty() && it == s.end();
}
int main() {
cout << "Enter some positive numbers" << endl;
string testInput = "";
while(true) {
cin >> testInput;
if(is_number(testInput)) {
testInput += " is a positive number";
cout << testInput << endl;
}
else {
cout << "invalid" << endl;
}
}
return EXIT_SUCCESS; //never exits
}
The code for the parent function:
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <cstring>
#include <array>
std::string exec(const char* cmd) {
std::array<char, 128> buffer;
std::string result;
std::unique_ptr<FILE, decltype(&_pclose)> pipe(_popen(cmd, "r"), _pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
for (int returnNum = 0; returnNum < 5; returnNum++) {
if(fgets(buffer.data(), buffer.size(), pipe.get()) == nullptr)
break;
result += buffer.data();
}
return result;
}
int main() {
std::cout << "Result: " << exec(".\\child.exe") << "." << std::endl;
system("PAUSE");
return EXIT_SUCCESS;
}
The parent function code was adapted from an answer given to How do I execute a command and get the output of the command within C++ using POSIX?. My understanding is the parent function opens the executable and allows me to send commands via the parent functions command line (not really sure how these are passed to the child process but it does work). If the child function was not in the infinite while loop, the result would be printed to the parent terminal.
Note that I will always need to call the child function a known number of times (hence the for loop). I also don't need this code to be perfect as it will just be me using the program.
Why is the result never returned even after 5 commands?
How do I get the result to return?
How do I send commands in the code of my parent program instead of typing them into the terminal of the parent function?
//DLL Code
#include <stdio.h>
extern "C"
{
__declspec(dllexport) void DisplayHelloFromDLL()
{
printf("Hello from DLL !\n");
}
}
//Program Accessing DLL
#include<windows.h>
#include<iostream>
#include<conio.h>
typedef void (*DisplayHelloFromDLLFuncPtr)();
using namespace std;
int main()
{
HINSTANCE hGetProcIDDLL = LoadLibrary("L:\\C_Learning\\Library\\MyLib\\Debug\\MyLib.dll");
if (!hGetProcIDDLL)
{
cout << "\nCould Not The Library";
return EXIT_FAILURE;
}
else
{
cout << "\nDLL is Loaded";
}
DisplayHelloFromDLLFuncPtr LibMainEntryPoint=(DisplayHelloFromDLLFuncPtr)GetProcAddress(hGetProcIDDLL, "DisplayHelloFromDLL");
if (!DisplayHelloFromDLL)
{
cout << "\nCould not locate the function";
return EXIT_FAILURE;
}
cout << DisplayHelloFromDLL();
return EXIT_SUCCESS;
_getch();
return 0;
}
Code executes till cout statement in else condition.
Receive Error while compiling for Function in DLL.
Error received 'DisplayHelloFromDLL': undeclared identifier
Ran Depends.exe which confirms about the function availability in DLL address space.
DLL and Sample Program is compiled with 32-bit environment.
6.Program sole purpose is to call function C DLL and print Hello From DLL message.
Any Suggestions ?
You named the variable holding the "DisplayHelloFromDLL" function pointer as "LibMainEntryPoint":
DisplayHelloFromDLLFuncPtr LibMainEntryPoint=(DisplayHelloFromDLLFuncPtr)GetProcAddress(hGetProcIDDLL, "DisplayHelloFromDLL");
but then you try to use it with different name (DisplayHelloFromDLL):
if (!DisplayHelloFromDLL) ...
Be consistent with the variable names, and the code should work.
change it to:
DisplayHelloFromDLLFuncPtr DisplayHelloFromDLL=(DisplayHelloFromDLLFuncPtr)GetProcAddress(hGetProcIDDLL, "DisplayHelloFromDLL");
I'm currently learning c++ from scratch, I've previously developed apps with C# using Visual Studio but I'm a total noob with C++, I'm trying to make a small console exe that releases and renews the ip while practicing using headers and differents .cpp files.
The issue is that when I run the local windows debugger from visual studio 2015 the code runs perfectly and does everything I'm trying to. But when I build and try to run the .exe file it goes into an infinite loop stating endlessly the output from the std::cout <<"Realizando ipconfig Release", I have localized the issue to when it tries to run the system("ipconfig /release"). Why does this happen? and How can I fix it?
This is the header
#pragma once
#ifndef HeaderIp
#define HeaderIp
int Release();
int Renew();
#endif // !HeaderIp
This is the release.cpp
#include <stdlib.h>
int Release()
{
if (system(nullptr)==0)
{
return 0;
}
else
{
system("ipconfig /release");
return 1;
}
}
This is the renew.cpp
#include <stdlib.h>;
int Renew()
{
if (system(nullptr)==0)
{
return 0;
}
else
{
system("ipconfig /renew");
return 1;
}
}
and finally this is the ipconfig.cpp
#include <iostream>
#include <stdlib.h>
#include "HeaderIp.h"
#include <stdio.h>
int main()
{
std::cout << "Realizando ipconfig Release" << std::endl;
int i = 0; //Bit de informacion de status de CPU
i = Release();
if (i == 0)
{
std::cout << "Error al liberar IP" << std::endl;
system("pause");
exit;
}
else
{
std::cout << "Ip Liberado correctamente" << std::endl;
}
i = Renew();
if (i == 0)
{
std::cout << "Error al renovar IP" << std::endl;
system("pause");
exit;
}
else
{
std::cout << "Ip renovado correctamente" << std::endl;
}
system("pause");
return 0;
}
It's unusual, and indeed generally discouraged to use system in C++. If you were to manage DHCP leases using IpReleaseAddress and IpRenewAddress, instead, you might find your problem disappears.
You can use std::cin.sync() instead of system("pause"), too.
exit; probably doesn't do what you want it to, as you're only referring to the function, you're not calling it, so... it'll do nothing.
The semicolon in #include <stdlib.h>; is an error, and you should be including <cstdlib> and <cstdio> rather than <stdlib.h> and <stdio.h>.
So I'm trying to load a .dylib file at runtime in c++ and calling a function within it. It does not seem to be any problem loading the file but when i try to create a function-pointer to the "print" function it's result is NULL.
Here is my code:
/* main.cpp */
#include <iostream>
#include <string>
#include <dlfcn.h>
#include "test.hpp"
int main(int argc, const char * argv[]) {
std::string path = argv[0];
std::size_t last = path.find_last_of("/");
// get path to execution folder
path = path.substr(0, last)+"/";
const char * filename = (path+"dylibs/libtest.dylib").c_str();
// open libtest.dylib
void* dylib = dlopen(filename, RTLD_LAZY);
if (dylib == NULL) {
std::cout << "unable to load " << filename << " Library!" << std::endl;
return 1;
}
// get print function from libtest.dylib
void (*print)(const char * str)= (void(*)(const char*))dlsym(dylib, "print");
if (print == NULL) {
std::cout << "unable to load " << filename << " print function!" << std::endl;
dlclose(dylib);
return 2;
}
// test the print function
print("Herro Word!");
dlclose(dylib);
return 0;
}
test dylib headerfile
/* test.hpp */
#ifndef test_hpp
#define test_hpp
void print(const char * str);
#endif
the dylib c++ file
#include <iostream>
#include "test.hpp"
void print(const char * str) {
std::cout << str << std::endl;
}
the output when running is:
unable to load /Users/usr/Library/Developer/Xcode/DerivedData/project/Build/Products/Debug/dylibs/libtest.dylib print function!
Program ended with exit code: 2
I am quite new to c++ and have never loaded dylibs before. Any help would be much appreciated!
Try qualifying the print function declaration with extern "C" to get around the name mangling that is likely going on.
Here's a nice article on the topic: http://www.tldp.org/HOWTO/C++-dlopen/theproblem.html (solution discussion on page following)
I have been asked to use MSFileReader from Thermo Fisher to read RAW files and do some peak picking for mass spectrometry data. I can load the DLL included in the package, but cannot access the functions. I have version 3.0. I am using Visual Studio Community 2015 as my compiler. My code is below.
#include <Windows.h>
#include <iostream>
#include <string>
double SampleWt;
double *pd = &SampleWt;
typedef std::string(*MYPROC)(int);
int main()
{
MYPROC ProcAdd;
HINSTANCE hinstLib = LoadLibrary(L"C:\\Nathan\\DanforthPrj\\MZmine- 2.16\\lib\\vendor_lib\\thermo\\MSFileReaderLib.dll");
if (!hinstLib)
{
std::cout << "\ncould Not Load the Library" << std::endl;
return EXIT_FAILURE;
}
else {
std::cout << "\nSuccess" << std::endl;
}
ProcAdd = (MYPROC)GetProcAddress(hinstLib, "Open");
if (NULL != ProcAdd)
{
std::cout << "\nfinaly" << std::endl;
}
//Resolve the function address 6
FreeLibrary(hinstLib);
return EXIT_SUCCESS;
}
Using a similar process, I can use other DLL files. What could be going wrong? I don't receive any error messages. The name of the function I am tryng to load is simply "Open".