Help with marshalling into char**

Y

YodaJ007

I'm attempting to inteface C# with the Ghostscript DLL. The function
I'm having trouble with is defined in C as:

int gsapi_init_with_args(void *instance, int argc, char **argv);

My interface code is:

[DllImport(DLL, EntryPoint = "gsapi_init_with_args", CallingConvention
= CallingConvention.StdCall, CharSet = CharSet.Ansi)]
private static extern int _initWithArgs(IntPtr instance, int argc, [In]
[Out] ref String[] argv);

But, the following code is failing, and I can't figure out why. If
the 2 argument to init_with_args is made to be 8, I get an invalid
operation fault saying memory has been corrupted. If I put it as 2,
while debugging the argsArray gets truncated down to an array of size
1 (containing only the first item). I can't see why it should be
modifying the input arguments. The code below closely matches the
code given in the C interface examples. If you leave the 2 in place,
the very next C# command yields an "Out of Memory" error. Can anyone
point out what I'm doing wrong?

string[] argsArray = new string[9];
int i = 0;

argsArray[i++] = "foobar"; // it doesn't
matter what this is according to documentation.
argsArray[i++] = "-dNOPAUSE";
argsArray[i++] = "-dBATCH";
argsArray[i++] = "-dSAFER";
argsArray[i++] = "-sDEVICE=tiff24nc"; // set output to
TIFF format, 24-bit RGB
argsArray[i++] = "-dMaxStripSize=8192"; // recommended
strip size for TIFF formats
argsArray[i++] = "-sOutputFile=" + outputFileName;
argsArray[i++] = inputPathPDF;

_initWithArgs(instancePtr, 2, ref argsArray);

I've tried removing the "[In][Out]" attributes in the method
definition, but nothing has seemed to work. I'm hoping the problem is
my C# code here.

Thank you.
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

I'm attempting to inteface C# with the Ghostscript DLL. The function
I'm having trouble with is defined in C as:

int gsapi_init_with_args(void *instance, int argc, char **argv);

My interface code is:

[DllImport(DLL, EntryPoint = "gsapi_init_with_args", CallingConvention
= CallingConvention.StdCall, CharSet = CharSet.Ansi)]
private static extern int _initWithArgs(IntPtr instance, int argc, [In]
[Out] ref String[] argv);

But, the following code is failing, and I can't figure out why. If
the 2 argument to init_with_args is made to be 8, I get an invalid
operation fault saying memory has been corrupted. If I put it as 2,
while debugging the argsArray gets truncated down to an array of size
1 (containing only the first item). I can't see why it should be
modifying the input arguments. The code below closely matches the
code given in the C interface examples. If you leave the 2 in place,
the very next C# command yields an "Out of Memory" error. Can anyone
point out what I'm doing wrong?

string[] argsArray = new string[9];
int i = 0;

argsArray[i++] = "foobar"; // it doesn't
matter what this is according to documentation.
argsArray[i++] = "-dNOPAUSE";
argsArray[i++] = "-dBATCH";
argsArray[i++] = "-dSAFER";
argsArray[i++] = "-sDEVICE=tiff24nc"; // set output to
TIFF format, 24-bit RGB
argsArray[i++] = "-dMaxStripSize=8192"; // recommended
strip size for TIFF formats
argsArray[i++] = "-sOutputFile=" + outputFileName;
argsArray[i++] = inputPathPDF;

_initWithArgs(instancePtr, 2, ref argsArray);

I've tried removing the "[In][Out]" attributes in the method
definition, but nothing has seemed to work. I'm hoping the problem is
my C# code here.

It should be simple.

The following works for me:

#include <stdio.h>

void __declspec(dllexport) f(int n, char **s)
{
int i;
for(i=0;i<n;i++)
{
printf("%s\n",s);
}
}

and:

using System;
using System.Runtime.InteropServices;

unsafe class MainClass
{
[DllImport("dd.dll")]
private static extern void f(int n, string[] s);
public static void Main(string[] args)
{
string[] s = { "A", "BB", "CCC" };
f(s.Length, s);
}
}

The only thing that immediately jump into my eyes from your
code is that you call with a argsArray[8] that is null.

You could start by fixing that.

And remove the in out, because I assume the args are not out.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top