Are there any way to link my program with Wine-compiled part? - c++

I am trying to use windows dll functionality in Linux.
My current solution is a compilation of a separate wine application, that uses dll and transfer requests/responses between dll and main application over IPC.
This works, but is a real overhead comparing to a simple dll calls.
I see that wine-compiled program usually is a bootstrapping-script and some .so, which (according to file utility) is normal linux dynamically linked library.
Are there any way to link that .so directly to my application? Are there any manual?

You may be able to use Winelib to write a Linux app that can use Windows DLLs.
EDIT:
For future reference:
libtest.c:
#include <stdio.h>
#include <windows.h>
int main(int argc, char* argv[])
{
HMODULE h;
h = LoadLibrary("cards.dll");
printf("%d\n", h);
}
Execution:
$ winegcc -m32 libtest.c
$ ./a.out
536936448

Related

Calling C++ program from a function?

So I'm pretty new to C++ and programming in general, and I'm trying to figure out how I can use code from this github program inside my own program. How do I write a function that calls the program and returns the results?
Here is the reference to std::system. With this you can run any command on a POSIX system.
#include <cstdlib>
#include <fstream>
#include <iostream>
int main()
{
std::system("ls -l >test.txt"); // execute the UNIX command "ls -l >test.txt"
std::cout << std::ifstream("test.txt").rdbuf();
}
If you need a other platform (e.g. Windows) take a look at boost process.
This is done by asking the system to create a new process, so your solution will depend on the system you are on.
You can use directly the system interfaces to create the process, or use a cross-platform third party wrapper such as Qt or boost.

Compile a static binary which code there a function gethostbyname

How to resolve compile a static binary which code include a function gethostbyname and if compiled without warning like this:
warning: Using 'gethostbyname' in statically linked applications
requires at runtime the shared libraries from the glibc version used
for linking
I compile on ubuntu 12.04 with command:
$ gcc -static lookup.c -o lookup
This is code for lookup.c:
/* lookup.c */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
extern int h_errno;
int main(int argc,char **argv) {
int x, x2;
struct hostent *hp;
for ( x=1; x<argc; ++x ) {
hp = gethostbyname(argv[x]);
if ( !hp ) {
fprintf(stderr,
"%s: host '%s'\n",
hstrerror(h_errno),
argv[x]);
continue;
}
printf("Host %s : \n" ,argv[x]);
printf(" Officially:\t%s\n", hp->h_name);
fputs(" Aliases:\t",stdout);
for ( x2=0; hp->h_aliases[x2]; ++x2 ) {
if ( x2 ) {
fputs(", ",stdout);
}
fputs(hp->h_aliases[x2],stdout);
}
fputc('\n',stdout);
printf(" Type:\t\t%s\n",
hp->h_addrtype == AF_INET
? "AF_INET" : "AF_INET6");
if ( hp->h_addrtype == AF_INET ) {
for ( x2=0; hp->h_addr_list[x2]; ++x2 ) {
printf(" Address:\t%s\n",
inet_ntoa( *(struct in_addr *)
hp->h_addr_list[x2]));
}
}
putchar('\n');
}
return 0;
}
I want to if I check via $ file lookup will get output like this:
lookup: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux),
statically linked, for GNU/Linux 2.6.24,
BuildID[sha1]=0x6fcb2684ad8e5e842036936abb50911cdde47c73, not stripped
Not like this:
lookup: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.24,
BuildID[sha1]=0xf9f18671751927bea80de676d207664abfdcf5dc, not stripped
If you commented with suggested I must use without static because different libc every linux I knew it, I hope you do not need to comment.
Why do I persist in for static?
Because there I need to do to mandatory use static, binary files must be static and not dynamic.
I have more than 2 weeks looking for this but so far have not succeeded.
Thanks for help me to resolve my heavy problem.
What you are asking for is going to be very difficult.
See this StackOverflow question about getaddrinfo. Basically, underneath getaddrinfo/gethostbyname is glibc's NSS layer. This allows a sysadmin to say "use DNS for resolving hostnames to IP addresses", or "use LDAP", or "don't use anything other than /etc/hosts". This control is at runtime; the sysadmin can at any point change the way hostnames are resolved to IPs.
Because of this flexibility, all of the name-resolution calls in glibc use helper libraries (plugins, basically) to do the grunt work of resolution. There's one shared library for LDAP addressing, one for files, one for DNS, one for YP, and so on and so on.
If you want your program to be 100% statically linked, you're going to have to go elsewhere (NOT gethostbyname) to convert a hostname to an IP address. You could do this with a resolver library like uDNS (not this exact one - there are similar tools available), but you should keep in mind that your binary is not going to do the right thing on systems which are configured not to use DNS!
Instead, I would recommend just leaving the program (technically) dynamically linked. If you really want to make sure it will run on any platform, you could even ship glibc with the binary - although doing this would require LGPL conformance. Leaving this one dynamic link in place will only mean you won't work on systems with the wrong glibc version - not a huge compatibility issue.
Speaking of license compliance, it's worth noting that if you statically link glibc, you most likely have to ship the source code for your entire application to comply with glibc's LGPL license. I am not a lawyer, and this is not qualified legal advice, but reading the LGPL makes it very clear that applications statically linking glibc must be open-source. See this StackOverflow question on the topic.
I get the same warning and to fix it I recompiled glibc. Turn on switch --enable-static-nss when configuring to get it to work.
I have 2 answers -
Keep the main part of your program statically linked, and separate out a single function program to just call gethostbyname(). Allow the latter to be dynamically linked. Using fork then exec execute this separate program to get the address for a domain name. Instead of fork then exec you could use system() though it takes longer (a whole millisecond) that should not be of concern since you're searching nameservers on the internet anyway, which takes a time.
Write the source code to do the DNS, as I have done. Compile it into an archive (.a) and have it searched in the static linking.
use ip instead of using domain name, that work for me

Is there a simple Program Files/Program Files (x86) directive for C++ in windows?

I am currently hard-coding the path to my application as follows:
const char* OriginCopyFile = "C:\\Program Files (x86)\\i-cut\\i-cut\\Origin_copy.txt";
This application is going to be running in both 32 and 64 systems. How can I detect the path without the file name in order to reuse it with several files and make it portable between architecture.
You can use GetModuleFileName to get the path to your executable, wherever it was installed or even moved later. You can then PathRemoveFileSpec to remove the executable name (or strchr() and friends if you want to support earlier versions than Windows 2000).
SHGetSpecialFolderPath(CSIDL_PROGRAM_FILES) will at least give the path to the program files directory. You'll have to deal with adding the rest of the path and file name.
You can use environment variables for this:
#include <stdio.h>
#include <stdlib.h>
int _tmain(int argc, _TCHAR* argv[])
{
char* programFiles = getenv("ProgramFiles(x86)");
if (programFiles==NULL)
{
programFiles = getenv("ProgramFiles");
}
printf(programFiles);
return 0;
}

Multiple application entry points

Recently I was trying to add unit tests to an existing binary by creating a extra (DLLMain) entry point to an application that already has a main entry point (it is a console exe). The application seemed to compile correctly although I was unable to use it as a DLL from my python unit test framework, all attempts to use the exe as a dll failed.
Has anyone any ideas or experience in adding extra application entry point with any input as to why this would or wouldn't work?
There are some problems which you should solve to implement what you want:
The exe must have relocation table (use linker switch /FIXED:NO)
The exe must exports at least one function - it's clear how to do this.
I recommend use DUMPBIN.EXE with no some switches (/headers, /exports and without switches) to examine the exe headers. You can compare the structure of your application with Winword.exe or outlook.exe which exports some functions.
If all this will not helps, I'll try to write a test EXE application which can be loaded as an exe and post the code here.
UPDATED: Just now verified my suggestion. It works. File Loadable.c looks like following
#include <windows.h>
#include <stdio.h>
EXTERN_C int __declspec(dllexport) WINAPI Sum (int x, int y);
EXTERN_C int __declspec(dllexport) WINAPI Sum (int x, int y)
{
return x + y;
}
int main()
{
printf ("2+3=%d\n", Sum(2,3));
}
The only important linker switch is /FIXED:NO which one can find in advanced part of linker settings. The program can run and produced the output "2+3=5".
Another EXE loaded the EXE as a DLL and calls Sum function:
#include <windows.h>
#include <stdio.h>
typedef int (WINAPI *PFN_SUM) (int x, int y);
int main()
{
HMODULE hModule = LoadLibrary (TEXT("C:\\Oleg\\ExeAsDll\\Loadable.exe"));
PFN_SUM fnSum = (PFN_SUM) GetProcAddress (hModule, "_Sum#8");
int res = fnSum (5,4);
printf ("5+4=%d\n", res);
return 0;
}
The program also can run and produced the output "5+4=9".
I don't know for sure, but I would guess that Windows simply refuses to load an EXE in-process and a DLL as a new process, plain and simple.
These questions appear to contain more detail:
Can the DllMain of an .exe be called?
DllMain in an exe?
The simplest way to get both behaviours in one executable image is to design it as a DLL, then use rundll32.exe to execute it standalone. There's no need to write your own wrapper.

How to create Target/Executables for my .cpp file

I create a simple test.cpp file in my Xcode project.
#include "MyTest.h"
#include <stdio.h>
int main(int argc, char** argv) {
printf ("Calling MyTest Main\n");
}
It compiles. I think I need to create a Target and Executables before I can launch in XCode.
But I need some help with these questions:
1. What kind of Target i should create for my simple .cpp file? It is not a GUI application.
2. How to specify this main in test.cpp to be the starting point of my Target and Executable?
Thank you.
1) You probably want a Command Line Tool application.
2) When you launch your tool, the mach kernel calls the start() function in the C Runtime Library, which invokes main() with the count of arguments (argc) and an array of argument string pointers (argv). So the main() that you show above is what will run.
You can use a special linker command to designate one of your own functions to be run instead of start(), but almost nobody does.