I'll start of by stating this is not specific to DB2. You are expecting
certain things to just "work" when calling a C function that takes a
structure from a C# code -- this actually requires a LOT of work on the
C# side to do. Typically, the compiler knows that C# "string" maps to
"char*" or "char[]" in C, for instance, but it does not make this
distinction for structure types.
You cannot just pass in a .NET object to a C API that is expecting a
pointer to a structure as an output parameter. You probably want to
catalog your C function as taking an IntPtr instead of an SQLCA. This
would require you to use "unsafe" code so that you can get the address
of the structure you create and pass it in as (IntPtr)&mySqlca, for
instance.
The SQLCA structure is a fixed-sized structure -- 136 bytes. Your SQLCA
is full of variable-sized String objects; there's no way, for example,
for the C# compiler to "know" when it does the transition from C# to C
code that it needs to make sure sqlcaid is only 8 bytes long, for
example. For instance, for the SQLSTATE, the C# compiler will likely
try to interpret the sqlstate as a char* (4 bytes pointing to an area of
memory) instead of a char[5] (5 bytes inline to the structure).
Please read up on the .NET documentation of "unsafe" modes before you
proceed down this path. What I'd actually recommend that you if you
still want to do something like this is to write C wrappers to the APIs
that do the parsing of the SQLCA, and returns errors to the .NET code
based on what your parse out of it.
Andy Meyer wrote:
Hi all,
I try to execute the "sqledrpd" - Api. I found it in the db2app.dll
renamed to sqledrpd_api, but my application crashes. Here's the
codesnippset.
Perhaps someone can help?!
Thanks in advance
Andy
[StructLayout(LayoutKind.Sequential)]
internal struct SQLCA
{
public string sqlcaid;
public long sqlcabc;
public long sqlcode;
public short sqlerrml;
public string sqlerrmc;
public string sqlerrp;
public long sqlerrd1;
public long sqlerrd2;
public long sqlerrd3;
public long sqlerrd4;
public long sqlerrd5;
public long sqlerrd6;
public string sqlwarn;
public string sqlstate;
}
[DllImport(@"db2App.dll", CharSet=CharSet.Auto)]
internal static extern int sqledrpd_api(string dbAlias, out SQLCA
sqlca);
and somewhere in my sourcecode:
public void DeleteDb(string dbName)
{
SQLCA sqlca = new SQLCA();
int ret = sqledrpd_api( dbName, out sqlca );
}