I'm trying to call a C routine from a pascal program, and pass string data back and forth. I can call it, I can pass integers back and forth ( thanks to Frank H ), but I can't pass strings. Attempts to assign data to a cstring either result in segmentation errors or garbage in the string.
The following is the C routine:
#include <stdio.h>
char c_str[13];
void c_print_str() { printf ("Now in C routine called from Pascal code.\n"); printf ("string is %s.\n", c_str); fflush (stdout); /* So the text really appears now. */ }
The following is the pascal program:
program str_trans(input);
(* This is an attempt to pass a string from a pascal program to a c function. The corresponding c code is in str_trans.c It is compiled with gpc --automake --unit-path=/home/x/pas str_trans.pas -o str_trans *)
{$L str_trans.c} {$X+}
procedure c_print_str; asmname 'c_print_str';
var char_ptr: ^char; c_str: cstring; asmname 'c_str'; external;
begin
new( char_ptr ); char_ptr^ := 'x'; writeln( char_ptr^ ); flush( output );
c_str := char_ptr;
writeln( 'calling c function' ); c_print_str; end.
As shown, it ends up with garbage in c_str. If I change the value of char_ptr^, the garbage changes.
If I try simple assignment in the pascal program, such as c_str := 'x'; or c_str[3] := 'x'; or c_str^ := char_ptr^ it compiles ok, but generates run-time segmentation errors.
So, the ideal help would be if someone could explain to me how to assign to c_str. If not, does anyone know how to pass string data between C and Pascal programs in some other manner?
Thanks, and happy solstace to all! HB
On 22 Dec 2007 at 12:02, Harmonious Botch wrote:
I'm trying to call a C routine from a pascal program, and pass string data back and forth. I can call it, I can pass integers back and forth ( thanks to Frank H ), but I can't pass strings. Attempts to assign data to a cstring either result in segmentation errors or garbage in the string.
[...] Your code is all wrong.
This is a better version of your Pascal program;
program str_trans(input);
uses strings; { non standard - but if you will use C strings, then you will need some of the routines exported by this unit - or you will need to write them yourself }
{$L str_trans.c} {$X+}
procedure c_print_str; external name 'c_print_str'; var char_ptr: cstring; c_str: array [0..12] of char; external name 'c_str'; begin char_ptr := strnew ('x and y'); writeln( char_ptr ); strcopy (c_str, char_ptr); writeln( 'calling c function' ); c_print_str; strdispose (char_ptr); end.
However, a better way (IMHO) than using global variables in your C program is for the C function to take a string parameter, and then pass a cstring to it in your Pascal program. You need to know the size of the buffer of the string being passed (e.g., an integer parameter can be used for this ), and you also need to decide who "owns" the pointer for subsequent disposal.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Thanks, Prof!
For anyone else who may have the same problem, a quick summary is that even though C uses pointers for strings, the pascal equivalent of a C string such as: char c[somenumber]; is not a pointer like: var c: ^char; but is: var c: array[0..(somenumber-1)];
Second try...
For anyone else who may have the same problem, a quick summary is that even though C uses pointers for strings, the pascal equivalent of a C string such as: char c[somenumber]; is not a pointer like: var c: ^char; but is: var c: array[0..(somenumber-1)] of char;
On 24 Dec 2007 at 11:46, Harmonious Botch wrote:
Thanks, Prof!
You're welcome :)
For anyone else who may have the same problem, a quick summary is that even though C uses pointers for strings, the pascal equivalent of a C string such as: char c[somenumber]; is not a pointer like: var c: ^char; but is: var c: array[0..(somenumber-1)]; --
Well, C constructs are not my forte, but as a rule of thumb, I think it is more like this:
char * = ^char char [n] = array [0..n-1] of char
Perhaps char * and char[n] mean the same thing in C - but not so in Pascal.
View this message in context: http://www.nabble.com/Assignment-of-cstrings-passed-to-C-routine-tp14472794 p14490826.html Sent from the Gpc mailing list archive at Nabble.com.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
For anyone else who may have the same problem, a quick summary...
I have a web page that describes how to link C++, Pascal, Fortran and C here:
http://alignment.hep.brandeis.edu/Software/Mixing_Manual.html
The example files talkes about in the manual are one level up:
http://alignment.hep.brandeis.edu/Software/
Yours, Kevan
Am Monday, dem 24. Dec 2007 schrieb Harmonious Botch:
For anyone else who may have the same problem, a quick summary is that even though C uses pointers for strings, the pascal equivalent of a C string such as: char c[somenumber];
This is not a pointer in C but a vector (array in pascal wording). A pointer would be "char *c".
is not a pointer like: var c: ^char; but is: var c: array[0..(somenumber-1)] of char;
When you use pointers in C, you can also use a pointer in Pascal. When you use a vector, you have to use the Pascal equivalent (Array).