Mail Archives: cygwin/2011/02/19/04:40:37
X-Recipient: | archive-cygwin AT delorie DOT com
|
X-SWARE-Spam-Status: | No, hits=-1.3 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,SPF_HELO_PASS,TW_CP,TW_FW,TW_TF,T_RP_MATCHES_RCVD,T_TO_NO_BRKTS_FREEMAIL
|
X-Spam-Check-By: | sourceware.org
|
To: | cygwin AT cygwin DOT com
|
From: | Jason Curl <jcurlnews AT arcor DOT de>
|
Subject: | Re: I want to use DLL compiled with Cygwin with VC(VS2008).
|
Date: | Sat, 19 Feb 2011 10:39:59 +0100
|
Lines: | 224
|
Message-ID: | <ijo35f$54i$1@dough.gmane.org>
|
References: | <201102120245 DOT p1C2juUX029959 AT omx12 DOT ms DOT so-net DOT ne DOT jp> <20110212025813 DOT GA20293 AT ednor DOT casa DOT cgf DOT cx> <201102140403 DOT p1E43cc8002240 AT omx11 DOT ms DOT so-net DOT ne DOT jp>
|
Mime-Version: | 1.0
|
User-Agent: | Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101207 Thunderbird/3.1.7
|
In-Reply-To: | <201102140403.p1E43cc8002240@omx11.ms.so-net.ne.jp>
|
X-IsSubscribed: | yes
|
Mailing-List: | contact cygwin-help AT cygwin DOT com; run by ezmlm
|
List-Id: | <cygwin.cygwin.com>
|
List-Unsubscribe: | <mailto:cygwin-unsubscribe-archive-cygwin=delorie DOT com AT cygwin DOT com>
|
List-Subscribe: | <mailto:cygwin-subscribe AT cygwin DOT com>
|
List-Archive: | <http://sourceware.org/ml/cygwin/>
|
List-Post: | <mailto:cygwin AT cygwin DOT com>
|
List-Help: | <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
|
Sender: | cygwin-owner AT cygwin DOT com
|
Mail-Followup-To: | cygwin AT cygwin DOT com
|
Delivered-To: | mailing list cygwin AT cygwin DOT com
|
On 14/02/2011 05:03, Y.Hosoi wrote:
> Thank you.
>
> However, it did not move well.
>
> If test.dll is done in LoadLibrary, Access Violation is generated.
>
> Are you still amused something?
>
>
> [main source code]
>
> #include "stdafx.h"
> #include "windows.h"
>
> #ifdef __cplusplus
> extern "C"{
> #endif
>
> typedef int (*TFUNC)(void);
>
> typedef void (*Tinit)(void);
>
> int _tmain(int argc, _TCHAR* argv[])
> {
> int i;
>
> HINSTANCE h;
> HINSTANCE hInstDLL;
>
> Tinit init;
> TFUNC DllFunction;
> DWORD ErrNo;
>
> h = LoadLibrary( TEXT( "cygwin1.dll" ) );
> init = (Tinit)GetProcAddress( h, "cygwin_dll_init" );
>
> init();
>
> hInstDLL = LoadLibrary( TEXT( "test.dll" ) ); /* !Access Violation! */
> if( hInstDLL == NULL )
> {
> ErrNo = GetLastError();
> return 0;
> }
> DllFunction = (TFUNC)GetProcAddress( hInstDLL, "hello" );
> i = DllFunction();
>
> FreeLibrary( hInstDLL );
> FreeLibrary( h );
>
> return 0;
> }
>
> #ifdef __cplusplus
> }
> #endif
>
Try the following code. This was pulled from the Cygwin sources. There
is a test case that does exactly this, loads cygwin1.dll dynamically.
You need to make sure you allocate stack. This was compiled with MINGW.
This is part of a larger program, so it might need some adjustments. The
function cygloadCRTStartup() is pretty much from the sources.
Note that the entry point needs to be set with the linker option:
-Wl,-entry -Wl,_cygloadCRTStartup AT 0
#include <windows.h>
#include <stdio.h>
#include "getopt.h"
#define CYGHELP_SUCCESS EXIT_SUCCESS
#define CYGHELP_ARG_ERROR 1
#define CYGHELP_DLL_NOT_FOUND 100
#define CYGHELP_DLL_NOT_SUPPORTED 101
#define CYGHELP_INTERNAL_ERROR 255
typedef void (__cdecl cdi_t)(void);
typedef void (__cdecl cctfwp_t)(const char *path, char *win32path);
typedef void (__cdecl cctfpp_t)(const char *path, char *posixpath);
int mainCRTStartup ();
int __stdcall cygloadCRTStartup ()
{
char padding[32768];
size_t delta;
int result;
char block[32768];
char *stackbase;
char *_stackbase;
char *_end;
_end = padding + sizeof(padding);
#ifdef __GNUC__
__asm__ (
"movl %%fs:4, %0"
:"=r"(stackbase)
);
#else
__asm {
mov eax, fs:[4];
mov stackbase, eax;
}
#endif
_stackbase = stackbase;
// We've gotten as close as we can to the top of the stack. Even
// subverting the entry point, though, still doesn't get us there-- I'm
// getting 64 bytes in use before the entry point. So we back up the data
// there and restore it when the destructor is called:
if ((_stackbase - _end) != 0) {
delta = (_stackbase - _end);
memcpy (block, _end, delta);
}
result = mainCRTStartup ();
memcpy(_end, block, delta);
return result;
}
int main(int argc, char **argv)
{
HMODULE cygwinDll;
DWORD winres;
cdi_t *cygwin_dll_init;
cctfwp_t *cygwin_conv_to_full_win32_path;
cctfpp_t *cygwin_conv_to_full_posix_path;
const char *dll = "cygwin1.dll";
const char *ppath = NULL;
const char *wpath = NULL;
char module[MAX_PATH];
char buff[MAX_PATH];
int i;
int c;
// Get any options the user provides
opterr = 0;
while ((c = getopt(argc, argv, "c:p:w:")) != -1) {
switch (c) {
case 'c':
dll = optarg;
break;
case 'p':
ppath = optarg;
break;
case 'w':
wpath = optarg;
break;
case '?':
if (optopt == 'c') {
fprintf(stderr, "Option -%c requires the full name for the Cygwin
DLL\n", optopt);
} else if (optopt == 'p') {
fprintf(stderr, "Option -%c requires the Posix path to convert\n",
optopt);
} else if (optopt == 'w') {
fprintf(stderr, "Option -%c requires the Windows path to convert\n",
optopt);
} else {
fprintf(stderr, "Unknown option -%c\n", optopt);
}
return CYGHELP_ARG_ERROR;
default:
fprintf(stderr, "Argument %c given, unknown handler\n", c);
return CYGHELP_INTERNAL_ERROR;
}
}
// Load the library and determine the full path to the library (as
// determined by windows)
cygwinDll = LoadLibrary(dll);
if (!cygwinDll) {
fprintf(stderr, "Couldn't find %s\n", dll);
return CYGHELP_DLL_NOT_FOUND;
}
winres = GetModuleFileName(cygwinDll, module, MAX_PATH);
if (!winres) {
winres = GetLastError();
fprintf(stderr, "GetModuleFilename returned error %d\n", winres);
return CYGHELP_DLL_NOT_SUPPORTED;
}
cygwin_dll_init = (cdi_t *)
GetProcAddress(cygwinDll, "cygwin_dll_init");
if (!cygwin_dll_init) {
fprintf(stderr, "Couldn't find cygwin_dll_init\n");
return CYGHELP_DLL_NOT_SUPPORTED;
}
cygwin_conv_to_full_win32_path = (cctfwp_t *)
GetProcAddress(cygwinDll, "cygwin_conv_to_full_win32_path");
if (!cygwin_conv_to_full_win32_path) {
fprintf(stderr, "Couldn't find cygwin_conv_to_full_win32_path\n");
return CYGHELP_DLL_NOT_SUPPORTED;
}
cygwin_conv_to_full_posix_path = (cctfpp_t *)
GetProcAddress(cygwinDll, "cygwin_conv_to_full_posix_path");
if (!cygwin_conv_to_full_posix_path) {
fprintf(stderr, "Couldn't find cygwin_conv_to_full_posix_path\n");
return CYGHELP_DLL_NOT_SUPPORTED;
}
// Initialise the library. The first line is always the name of the
// module. Then we print the result that the user expects. This allows
// programs to know what library is in use and to easily parse the output
// for their needs
cygwin_dll_init();
printf("%s\n", module);
if (ppath) {
cygwin_conv_to_full_win32_path(ppath, buff);
printf("%s\n", buff);
}
if (wpath) {
cygwin_conv_to_full_posix_path(wpath, buff);
printf("%s\n", buff);
}
// We've finished now, so let's exit
FreeLibrary(cygwinDll);
return CYGHELP_SUCCESS;
}
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
- Raw text -