- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I realy spent to much time on this issue and I desperately need help.
I'm actually using the Compaq Visual Fortran. I want to call a cpp dll and pass a string to a function.
This is my fortran routine:
program call_dll
implicit none
! Variables
real*4, pointer ::f(:)
real*4 ::a
CHARACTER*33 sFileName
INTERFACE
function read_ras_format(sFileName)
!dec$ attributes stdcall ,dllimport,alias:'_read_ras_format' :: read_ras_format
real*4, pointer::read_ras_format(:)
character*33 sFileName
!character :: strFileName
END function read_ras_format
END INTERFACE
! Body of simple_dll_test
sFileName = 'E:\\temp\\SHA00200604010046RF.ras' // CHAR(0)
f => read_ras_format(sFileName)
a=f(1)
end program
and this is my cpp code:
extern "C"
float * __stdcall read_ras_format(char *in_fileName, int fileName_length)
{
cout<<"in_fileName: "<
}
This is what I get:
in_fileName: _$@ fileName_length: 69
_______________
I read a lot of forum post about this issue, and I tried almost everything.
What am I doing wrong?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
extern "C"
float * __stdcall read_ras_format(char *in_fileName, int fileName_length)
{
cout<<"in_fileName: "<
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I do return a float value, I just didn't paste it in my post because the return value is not the issue.I tested thecpp function by calling it from a cpp code and it works well. The problem us passing the string from forrtran to cpp.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I do return a float value, I just didn't paste it in my post because the return value is not the issue.I tested thecpp function by calling it from a cpp code and it works well. The problem us passing the string from forrtran to cpp.
Shilosh, I replied to your post in comp.lang.fortran yesterday. Here it is again, for everyone's convenience:
Like Arjen said, you cannot mix Fortran and C pointers like that (at least not arrays). The rest of your code looks OK (and would likely have worked indeed with a void or a plain vanilla function). It seems that something ugly happened on the stack here.
What you can do is to declare the C function as returning an integer of address size, then dereference that into an array using a cray (integer) pointer. (It's unportable, but the rest of your code isn't portable either, so it doesn't matter).
Along the lines of (my changes uppercase):
[cpp]REAL:: F(*); POINTER(pF,F) !An integer (Cray) pointer interface function read_ras_format(sFileName) !dec$ attributes stdcall ,dllimport,alias:'_read_ras_format' :: read_ras_format INTEGER(INT_PTR_KIND())::read_ras_format ... pF = read_ras_format(sFileName) !et voila: DO i=1,SOMETHING WRITE(*,*) F(i) END DO [/cpp]
====
where SOMETHING is the array size -- I assume you know it by some means, because i don't see it referenced anyway in your original code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
//
#include "iostream.h"
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
};
int read_ras_format(char* in_fileName, int fileName_length)
{
cout<<"in_fileName: "<< in_fileName<<"n fileName_length: "<
return 1;
};
Fortran code
-------
!****************************************************************************
!
! PROGRAM: fcallsCPP
!
! PURPOSE: Example of Fortran calling C++
!Since the C++ function in a DLL calls cout, and since the DLL
!is linked using single threaded DLL libraries, this Fortran
!project should be linked using the same libraries if you want
!the cout output to appear in the console window.
!
!****************************************************************************
PROGRAM CALL_DLL
IMPLICIT NONE
! VARIABLES
CHARACTER*33 SFILENAME
INTEGER RETURNVALUE
INTERFACE
INTEGER FUNCTION READ_RAS_FORMAT(SFILENAME, LENGTH)
!DEC$ ATTRIBUTES DLLIMPORT,ALIAS:'_read_ras_format' :: READ_RAS_FORMAT
!DEC$ ATTRIBUTES REFERENCE :: SFILENAME
!DEC$ ATTRIBUTES VALUE :: LENGTH
CHARACTER*33 SFILENAME
INTEGER LENGTH
END FUNCTION READ_RAS_FORMAT
END INTERFACE
PRINT *, 'HELLO WORLD'
! Body of simple_dll_test
!Note: you do not need to double up on the back slashes in a character string if
!you explicitly add the null-terminator character to a string. Only if you use the
!"dkjv\akdj\vd"C format does the compiler need to be told that the first backslash
!in each pair is to be kept and that it is not the signal for a special control character
!
SFILENAME = 'E:tempSHA00200604010046RF.ras' // CHAR(0)
RETURNVALUE = read_ras_format(SFILENAME, LEN_TRIM(SFILENAME))
END PROGRAM

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page