Returning chars from static C libraries

Returning chars from static C libraries

Bild des Benutzers Robin C.

 Hello there,

Sorry if my post is a little basic and/or makes no sense. I have only just started working with Fortran. I'm trying to call a C function which populates resultValue with the return value. This is how it looked:

extern "C" void sqlSelect(char*resultValue,intlength,char*dataBase,char*query,intreturnValue)

I was able to get data from this with the following:

cSelectReturn=SQLSELECT(cFile//CHAR(0), TRIM(cSelectQuery))

Now, I since I probably should use an interface I've changed it a bit:

void sqlSelect(char*resultValue,char*dataBase,char*query,intreturnValue)

....

INTERFACE

SUBROUTINESQLSELECT(resultValue, dataBase, query, returnValue) BIND(C, NAME="sqlSelect")

USE iso_c_binding,ONLY: c_char, c_int

CHARACTER(kind=c_char) :: resultValue(*)

CHARACTER(kind=c_char) :: dataBase(*)

CHARACTER(kind=c_char) :: query(*)

INTEGER(kind=c_int) :: returnValue

END SUBROUTINESQLSELECT

END INTERFACE

CALL SQLSELECT(cSelectReturn, cFile//CHAR(0), TRIM(cSelectQuery),iReturnValue)

Now I get an unhandled exception returning from the call.

Using an INTERFACE, how does one return one (and more) parameters, without it blowing up in one's face?

 

4 Beiträge / 0 neu
Letzter Beitrag
Nähere Informationen zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.
Bild des Benutzers Steve Lionel (Intel)

I will be the first to admit that I am not a C expert, but something seems wrong in your problem description.  The C declaration of the procedure doesn't match how you're calling it from C, and what you typed would not even compile, I think. What is the real C declaration of that routine?

Steve
Bild des Benutzers Robin C.

Ah, sorry. I was ctrl-z'ing my way back and didn't go far enough. The working example, from memory as I'm on the bus, would have been:

extern "C" void sqlSelect(char* resultValue, int vLength, char* dataBase, char* query)

It worked fine without using an interface. From what I understand, the first 2 parameters are handled automatically as the return for the function. So if you so "something = CALL(....)", the "something" can be automatically added as the first parameter with it's length as the second.

The problem I have is that I want to have multiple return values from the function, so I can't do the above.

Bild des Benutzers Robin C.

It turns out, I was managing to return more data than expected, causing a problem between the two.

For reference:

.cpp:

extern "C"

{

void sqlExec(char*dataBase,char*query,intreturnValue)

{

<code>

}

}

.FOR

INTERFACE

SUBROUTINESQLEXEC(dataBase, query, returnValue)BIND(C, NAME="sqlExec")

USE iso_c_binding,ONLY: c_char, c_int

CHARACTER(kind=c_char) :: dataBase(*)

CHARACTER(kind=c_char) :: query(*)

INTEGER(kind=c_int) :: returnValue

END SUBROUTINE SQLEXEC

END INTERFACE

INTERFACE

Works a treat. Just need to get some decent safeguards for the variable sizing and so on.

 

Melden Sie sich an, um einen Kommentar zu hinterlassen.