Hi,
(This almost certainly has little, if anything, to do with perl.)
I have (a commercial version of) VC 7.0, and a perl-5.10.0 built using that
compiler.
I also have MinGW, and a perl-5.10.0 built using that MinGW compiler.
I have a test dll (named mydll.dll) that exports a function named
'd_one_arg'.
That function takes a single 'int' arg, and returns the value of that int
divided by 7. (The return value is a double.)
In a nutshell, there's no problem with MinGW, but with VC 7.0 the following
Inline::C script always segfaults around the time that the foo() function
exits:
------------------------------------------------
use warnings;
use Inline C => Config =>
BUILD_NOISY => 1;
use Inline C => <<'EOC';
typedef double (CALLBACK* FUNC2)(int);
SV * load_library (SV * dll) {
return newSVuv((HMODULE)LoadLibrary((LPCTSTR)SvPV_nolen(dll)));
}
SV * foo(SV * x, SV * hinstLib) {
FUNC2 ProcAdd;
BOOL freelib, fRunTimeLinkSuccess = FALSE;
double ret = 0;
if ((HMODULE)SvUV(hinstLib) != NULL) {
ProcAdd = (FUNC2) GetProcAddress((HMODULE)SvUV(hinstLib),
"d_one_arg");
if (fRunTimeLinkSuccess = (ProcAdd != NULL)) {
ret = ProcAdd((int)SvIV(x));
}
else printf("GetProcAddress() failed\n");
freelib = FreeLibrary((HMODULE)SvUV(hinstLib));
printf("freelib: %d\nreturn: %f\n", freelib, ret);
return newSVnv(ret);
}
else {
printf("LoadLibrary() failed\n");
return newSVnv(ret);
}
}
EOC
$lib = load_library("mydll");
$z = foo(123, $lib);
print $z, "\n";
------------------------------------------------
It makes no difference if $lib is instead assigned the return value of
Win32::LoadLibrary("mydll").
It makes no difference whether the dll was built using MinGW or VC 7.0.
Running that script in the VC 7.0 environment produces:
freelib: 1
return: 17.571429
[Then a segfault]
So, I'm thinking the segfault is caused by either:
a) 'return newSVnv(ret);'
or
b) the exiting of the foo() function;
or
c)'print $z, "\n";'
If I rewrite foo() so that it loads the mydll.dll library itself (instead of
taking a handle to it as its second arg) then there's no problem. That is,
there's no problem if foo() looks like:
-------------------------------------------
SV * foo(SV * x) {
HMODULE hinstLib;
FUNC2 ProcAdd;
BOOL freelib, fRunTimeLinkSuccess = FALSE;
double ret = 0;
hinstLib = LoadLibrary("mydll");
if (hinstLib != NULL) {
ProcAdd = (FUNC2) GetProcAddress(hinstLib, "d_one_arg");
if (fRunTimeLinkSuccess = (ProcAdd != NULL)) {
ret = ProcAdd((int)SvIV(x));
}
else printf("GetProcAddress() failed\n");
freelib = FreeLibrary(hinstLib);
printf("freelib: %d\nreturn: %f\n", freelib, ret);
return newSVnv(ret);
}
else {
printf("LoadLibrary() failed\n");
return newSVnv(ret);
}
}
-------------------------------------------
That (correctly) produces:
freelib: 1
return: 17.571429
17.5714285714286
So what is it that causes the first version of foo() to segfault ?
(I've also tried things out on a perl-5.8.8 built with the VC 7.0 compiler,
and the behaviour there is exactly the same as for 5.10.0.)
Cheers,
Rob
_______________________________________________
Perl-Win32-Users mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs