473,761 Members | 1,764 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Help please with pointers to callbacks in structs

I am very new to C# programming and have run into a problem.

I apologize for the repost of this article. For some reason, my news
reader attached it to an existing thread.

First off, I have an SDK that I have written for C/C++ and would like to
port it to C# if at all possible.

Basically, I've got a structure that I need to pass to the C-style DLL
(i.e. no mangled names - everything is __stdcall). This structure needs
to contain pointers to callback functions that the DLL can use to notify
the C# application when certain events occur. In addition, I need to use
SetEnvironmentV ariable and pass a string containing a pointer to a
character array for special processing by the DLL. I've included some
code that shows basically everything I'm looking to do.

To save time, I understand how to get access to exported functions within
DLLs.
// this structure will be filled by the DLL and will be passed
// to the callback for function2, (i.e. FnPtr2's typedef)

typedef struct _toPassAsArgume ntStruct
{
int a;
int b;
double c;
} TO_PASS_AS_ARGU MENT;
// these are the typedef's for two callback functions that will be
// stored in the structure, DEMOSTRUCT

typedef BOOL (__stdcall *FnPtr1)(DWORD i, char *path, DWORD pathLength);
typedef BOOL (__stdcall *FnPtr2)(TO_PAS S_AS_ARGUMENT *structure);
typedef struct _demoStruct
{
FnPtr1 function1;
FnPtr2 function2;
} DEMOSTRUCT;
char global_text[5] = {"test"};
// MyFunction1 and MyFunction2 are called by the DLL

BOOL MyFunction1(DWO RD i, char *path, DWORD pathLength)
{
strcpy(path, "unknown");
return TRUE;
}

BOOL MyFunction2(TO_ PASS_AS_ARGUMEN T *structure)
{
structure->a = 5;
return TRUE;
}
// simple_function is called by the non-DLL (i.e. the application)

void simple_function ()
{
char text[128] = {0};

DEMOSTRUCT ds = {0};

// Are these four statements possible in C#?

ds.function1 = MyFunction1;
ds.function2 = MyFunction2;

// the contents of 'text' will be passed to the DLL.
sprintf(text, "%x", &global_text );

SetEnvironmentV ariable("test", text);
}
--

TIA,
Brian
Nov 16 '05 #1
23 2243
Hi,
see inline;

<Brian> wrote in message news:10******** *****@corp.supe rnews.com...
I am very new to C# programming and have run into a problem.

I apologize for the repost of this article. For some reason, my news
reader attached it to an existing thread.

First off, I have an SDK that I have written for C/C++ and would like to
port it to C# if at all possible.

Basically, I've got a structure that I need to pass to the C-style DLL
(i.e. no mangled names - everything is __stdcall). This structure needs
to contain pointers to callback functions that the DLL can use to notify
the C# application when certain events occur. In addition, I need to use
SetEnvironmentV ariable and pass a string containing a pointer to a
character array for special processing by the DLL. I've included some
code that shows basically everything I'm looking to do.

To save time, I understand how to get access to exported functions within
DLLs.
// this structure will be filled by the DLL and will be passed
// to the callback for function2, (i.e. FnPtr2's typedef)

typedef struct _toPassAsArgume ntStruct
{
int a;
int b;
double c;
} TO_PASS_AS_ARGU MENT;
In c#:

[StructLayout(St ructLayout.Sequ ential)]
public struct PassAsArgStruct
{
public int a;
public int b;
public double c;
}


// these are the typedef's for two callback functions that will be
// stored in the structure, DEMOSTRUCT

typedef BOOL (__stdcall *FnPtr1)(DWORD i, char *path, DWORD pathLength);
typedef BOOL (__stdcall *FnPtr2)(TO_PAS S_AS_ARGUMENT *structure);
Declare a delegate for each callback:
public delegate bool DelFn1(uint i, IntPtr pPath, uint pathLength);
public delegate bool DelFn2(ref ToPassAsArgStru ct structure);


typedef struct _demoStruct
{
FnPtr1 function1;
FnPtr2 function2;
} DEMOSTRUCT;
In c#: (use the delegates)

[StructLayout(St ructLayout.Sequ ential)]
public struct DemoStruct
{
public DelFn1 function1;
public DelFn2 function2;
}


// MyFunction1 and MyFunction2 are called by the DLL

BOOL MyFunction1(DWO RD i, char *path, DWORD pathLength)
{
strcpy(path, "unknown");
return TRUE;
}
[DllImport("kern el32.dll",CharS et=CharSet.Ansi )]
public static extern long lstrcpyA (IntPtr pDst, string sSrc);

private bool MyFunction1(uin t i, IntPtr pPath, uint pathLength)
{
// TODO check pathLength before writing
lstrcpyA (pPath, "unknown");
return true;
}

BOOL MyFunction2(TO_ PASS_AS_ARGUMEN T *structure)
{
structure->a = 5;
return TRUE;
}
In c#:

private bool MyFunction2(ref ToPassAsArgStru ct s)
{
s.a = 5;
return true;
}
char global_text[5] = {"test"};

// simple_function is called by the non-DLL (i.e. the application)

void simple_function ()
{
char text[128] = {0};

DEMOSTRUCT ds = {0};

// Are these four statements possible in C#?

ds.function1 = MyFunction1;
ds.function2 = MyFunction2;

// the contents of 'text' will be passed to the DLL.
sprintf(text, "%x", &global_text );

SetEnvironmentV ariable("test", text);
[DllImport("kern el32.dll",CharS et=CharSet.Auto )]
public static extern bool SetEnvironmentV ariable (string sName, string
sValue);

private DemoStruct ds;
private IntPtr pGlobalText = IntPtr.Zero;

void SimpleFunction( )
{
ds = new DemoStruct();
ds.function1 = new DelFn1( MyFunction1 );
ds.function2 = new DelFn2( MyFunction2 );

// Allocate unmanaged memory the dll can read/write
pGlobalText = Marshal.AllocHG lobal (5);

lstrcpyA ( pGlobalText, "test" ); // write

// pass pointer as hex string value
SetEnvironmentV ariable("test", pGlobalText.ToI nt32().ToString ("X") );
}

* After this function you can :
- read from globaltext
Console.WriteLi ne ( Marshal.PtrToSt ringAnsi( pGlobalText ) ); /// READ

- write to globaltext
lstrcpyA ( pGlobalText, text );

- cleanup globaltext
(only if dll doesn't need globaltext anymore)
Marshal.FreeHGl obal( pGlobalText );
HTH,
greetings


}
--

TIA,
Brian

Nov 16 '05 #2
Thank you so much! I REALLY appreciate your taking the time to step me
through this!

I'll give it a try and see what happens.

Brian

BMermuys <so*****@someon e.com> wrote:
Hi,
see inline; <Brian> wrote in message news:10******** *****@corp.supe rnews.com...
I am very new to C# programming and have run into a problem.

I apologize for the repost of this article. For some reason, my news
reader attached it to an existing thread.

First off, I have an SDK that I have written for C/C++ and would like to
port it to C# if at all possible.

Basically, I've got a structure that I need to pass to the C-style DLL
(i.e. no mangled names - everything is __stdcall). This structure needs
to contain pointers to callback functions that the DLL can use to notify
the C# application when certain events occur. In addition, I need to use
SetEnvironmentV ariable and pass a string containing a pointer to a
character array for special processing by the DLL. I've included some
code that shows basically everything I'm looking to do.

To save time, I understand how to get access to exported functions within
DLLs.
// this structure will be filled by the DLL and will be passed
// to the callback for function2, (i.e. FnPtr2's typedef)

typedef struct _toPassAsArgume ntStruct
{
int a;
int b;
double c;
} TO_PASS_AS_ARGU MENT;
In c#: [StructLayout(St ructLayout.Sequ ential)]
public struct PassAsArgStruct
{
public int a;
public int b;
public double c;
}

// these are the typedef's for two callback functions that will be
// stored in the structure, DEMOSTRUCT

typedef BOOL (__stdcall *FnPtr1)(DWORD i, char *path, DWORD pathLength);
typedef BOOL (__stdcall *FnPtr2)(TO_PAS S_AS_ARGUMENT *structure); Declare a delegate for each callback:
public delegate bool DelFn1(uint i, IntPtr pPath, uint pathLength);
public delegate bool DelFn2(ref ToPassAsArgStru ct structure);

typedef struct _demoStruct
{
FnPtr1 function1;
FnPtr2 function2;
} DEMOSTRUCT; In c#: (use the delegates) [StructLayout(St ructLayout.Sequ ential)]
public struct DemoStruct
{
public DelFn1 function1;
public DelFn2 function2;
}

// MyFunction1 and MyFunction2 are called by the DLL

BOOL MyFunction1(DWO RD i, char *path, DWORD pathLength)
{
strcpy(path, "unknown");
return TRUE;
} [DllImport("kern el32.dll",CharS et=CharSet.Ansi )]
public static extern long lstrcpyA (IntPtr pDst, string sSrc); private bool MyFunction1(uin t i, IntPtr pPath, uint pathLength)
{
// TODO check pathLength before writing
lstrcpyA (pPath, "unknown");
return true;
}
BOOL MyFunction2(TO_ PASS_AS_ARGUMEN T *structure)
{
structure->a = 5;
return TRUE;
}

In c#:

private bool MyFunction2(ref ToPassAsArgStru ct s)
{
s.a = 5;
return true;
}
char global_text[5] = {"test"};

// simple_function is called by the non-DLL (i.e. the application)

void simple_function ()
{
char text[128] = {0};

DEMOSTRUCT ds = {0};

// Are these four statements possible in C#?

ds.function1 = MyFunction1;
ds.function2 = MyFunction2;

// the contents of 'text' will be passed to the DLL.
sprintf(text, "%x", &global_text );

SetEnvironmentV ariable("test", text); [DllImport("kern el32.dll",CharS et=CharSet.Auto )]
public static extern bool SetEnvironmentV ariable (string sName, string
sValue); private DemoStruct ds;
private IntPtr pGlobalText = IntPtr.Zero; void SimpleFunction( )
{
ds = new DemoStruct();
ds.function1 = new DelFn1( MyFunction1 );
ds.function2 = new DelFn2( MyFunction2 ); // Allocate unmanaged memory the dll can read/write
pGlobalText = Marshal.AllocHG lobal (5); lstrcpyA ( pGlobalText, "test" ); // write // pass pointer as hex string value
SetEnvironmentV ariable("test", pGlobalText.ToI nt32().ToString ("X") );
} * After this function you can :
- read from globaltext
Console.WriteLi ne ( Marshal.PtrToSt ringAnsi( pGlobalText ) ); /// READ - write to globaltext
lstrcpyA ( pGlobalText, text ); - cleanup globaltext
(only if dll doesn't need globaltext anymore)
Marshal.FreeHGl obal( pGlobalText );
HTH,
greetings



}
--

TIA,
Brian

Nov 16 '05 #3
Hi,

I failed to mention that I'll be using an exported function within a
custom DLL that I'll need to pass the following structure to. Will there
be any problems with the garbage collection freeing up the pointers to my
callbacks? I need the callbacks to be available throughout the life-cycle
of the program. The structure itself can be discarded as my DLL simply
copies the contents into its own format.

basically...

// dll function prototype

void __stdcall AssignCallbacks (DemoStruct *pDemoStruct);

I'm guessing the C# code would be...

[DllImport("mydl l.dll",CharSet= CharSet.Ansi)]
public static extern void AssignCallbacks (ref DemoStruct pDemoStruct);

.... and I would call it like so ...

void SimpleFunction( )
{
// DemoStruct as is defined below...

ds = new DemoStruct();
ds.function1 = new DelFn1( MyFunction1 );
ds.function2 = new DelFn2( MyFunction2 );

AssignCallbacks (ds);
}

Thanks,
Brian

BMermuys <so*****@someon e.com> wrote:
[StructLayout(St ructLayout.Sequ ential)]
public struct DemoStruct
{
public DelFn1 function1;
public DelFn2 function2;
} [DllImport("kern el32.dll",CharS et=CharSet.Ansi )]
public static extern long lstrcpyA (IntPtr pDst, string sSrc); private bool MyFunction1(uin t i, IntPtr pPath, uint pathLength)
{
// TODO check pathLength before writing
lstrcpyA (pPath, "unknown");
return true;
}

private bool MyFunction2(ref ToPassAsArgStru ct s)
{
s.a = 5;
return true;
}

[DllImport("kern el32.dll",CharS et=CharSet.Auto )]
public static extern bool SetEnvironmentV ariable (string sName, string
sValue);

private DemoStruct ds;
private IntPtr pGlobalText = IntPtr.Zero;

void SimpleFunction( )
{
ds = new DemoStruct();
ds.function1 = new DelFn1( MyFunction1 );
ds.function2 = new DelFn2( MyFunction2 );

// Allocate unmanaged memory the dll can read/write
pGlobalText = Marshal.AllocHG lobal (5);

lstrcpyA ( pGlobalText, "test" ); // write

// pass pointer as hex string value
SetEnvironmentV ariable("test", pGlobalText.ToI nt32().ToString ("X") );
}

* After this function you can :
- read from globaltext
Console.WriteLi ne ( Marshal.PtrToSt ringAnsi( pGlobalText ) ); /// READ - write to globaltext
lstrcpyA ( pGlobalText, text ); - cleanup globaltext
(only if dll doesn't need globaltext anymore)
Marshal.FreeHGl obal( pGlobalText );
HTH,


Believe me, it did. Thanks!
Brian
Nov 16 '05 #4
Hi,

<Brian> wrote in message news:10******** *****@corp.supe rnews.com...
Hi,

I failed to mention that I'll be using an exported function within a
custom DLL that I'll need to pass the following structure to. Will there
be any problems with the garbage collection freeing up the pointers to my
callbacks?
Yes if you don't keep a reference to the struct.

Make sure you can access the DemoStruct variable during the entire program
(this is the same as saying you should keep a reference somewhere). Then
the GC won't cleanup the delegates. As long as the delegates are alive and
not changed the function pointers remain valid.

Eg. declare demostruct as a instance variable or static variable in a class
(*not* as a local variable inside a function ).
I need the callbacks to be available throughout the life-cycle
of the program. The structure itself can be discarded as my DLL simply
Yes, your dll may copy the struct. But you must keep the managed struct
after 'assigncallback s'.
copies the contents into its own format.

basically...

// dll function prototype

void __stdcall AssignCallbacks (DemoStruct *pDemoStruct);

I'm guessing the C# code would be...

[DllImport("mydl l.dll",CharSet= CharSet.Ansi)]
public static extern void AssignCallbacks (ref DemoStruct pDemoStruct);
Yes that's it.

Don't hesitate to ask more if required.

hth,
greetings


... and I would call it like so ...

void SimpleFunction( )
{
// DemoStruct as is defined below...

ds = new DemoStruct();
ds.function1 = new DelFn1( MyFunction1 );
ds.function2 = new DelFn2( MyFunction2 );

AssignCallbacks (ds);
}

Thanks,
Brian

BMermuys <so*****@someon e.com> wrote:
[StructLayout(St ructLayout.Sequ ential)]
public struct DemoStruct
{
public DelFn1 function1;
public DelFn2 function2;
}

[DllImport("kern el32.dll",CharS et=CharSet.Ansi )]
public static extern long lstrcpyA (IntPtr pDst, string sSrc);

private bool MyFunction1(uin t i, IntPtr pPath, uint pathLength)
{
// TODO check pathLength before writing
lstrcpyA (pPath, "unknown");
return true;
}

private bool MyFunction2(ref ToPassAsArgStru ct s)
{
s.a = 5;
return true;
}

[DllImport("kern el32.dll",CharS et=CharSet.Auto )]
public static extern bool SetEnvironmentV ariable (string sName, string
sValue);

private DemoStruct ds;
private IntPtr pGlobalText = IntPtr.Zero;

void SimpleFunction( )
{
ds = new DemoStruct();
ds.function1 = new DelFn1( MyFunction1 );
ds.function2 = new DelFn2( MyFunction2 );

// Allocate unmanaged memory the dll can read/write
pGlobalText = Marshal.AllocHG lobal (5);

lstrcpyA ( pGlobalText, "test" ); // write

// pass pointer as hex string value
SetEnvironmentV ariable("test", pGlobalText.ToI nt32().ToString ("X") ); }

* After this function you can :
- read from globaltext
Console.WriteLi ne ( Marshal.PtrToSt ringAnsi( pGlobalText ) ); /// READ

- write to globaltext
lstrcpyA ( pGlobalText, text );

- cleanup globaltext
(only if dll doesn't need globaltext anymore)
Marshal.FreeHGl obal( pGlobalText );


HTH,


Believe me, it did. Thanks!
Brian

Nov 16 '05 #5
Thanks for the help. It is very much appreciated.

I figured that the GC might behave the way that you described, but keeping
an active reference shouldn't be too difficult.

Thanks,
Brian
Hi, <Brian> wrote in message news:10******** *****@corp.supe rnews.com...
Hi,

I failed to mention that I'll be using an exported function within a
custom DLL that I'll need to pass the following structure to. Will there
be any problems with the garbage collection freeing up the pointers to my
callbacks?
Yes if you don't keep a reference to the struct. Make sure you can access the DemoStruct variable during the entire program
(this is the same as saying you should keep a reference somewhere). Then
the GC won't cleanup the delegates. As long as the delegates are alive and
not changed the function pointers remain valid. Eg. declare demostruct as a instance variable or static variable in a class
(*not* as a local variable inside a function ).
I need the callbacks to be available throughout the life-cycle
of the program. The structure itself can be discarded as my DLL simply Yes, your dll may copy the struct. But you must keep the managed struct
after 'assigncallback s'. copies the contents into its own format.

basically...

// dll function prototype

void __stdcall AssignCallbacks (DemoStruct *pDemoStruct);

I'm guessing the C# code would be...

[DllImport("mydl l.dll",CharSet= CharSet.Ansi)]
public static extern void AssignCallbacks (ref DemoStruct pDemoStruct); Yes that's it. Don't hesitate to ask more if required. hth,
greetings



... and I would call it like so ...

void SimpleFunction( )
{
// DemoStruct as is defined below...

ds = new DemoStruct();
ds.function1 = new DelFn1( MyFunction1 );
ds.function2 = new DelFn2( MyFunction2 );

AssignCallbacks (ds);
}

Thanks,
Brian

BMermuys <so*****@someon e.com> wrote:
> [StructLayout(St ructLayout.Sequ ential)]
> public struct DemoStruct
> {
> public DelFn1 function1;
> public DelFn2 function2;
> }

> [DllImport("kern el32.dll",CharS et=CharSet.Ansi )]
> public static extern long lstrcpyA (IntPtr pDst, string sSrc);

> private bool MyFunction1(uin t i, IntPtr pPath, uint pathLength)
> {
> // TODO check pathLength before writing
> lstrcpyA (pPath, "unknown");
> return true;
> }
>
> private bool MyFunction2(ref ToPassAsArgStru ct s)
> {
> s.a = 5;
> return true;
> }
>
> [DllImport("kern el32.dll",CharS et=CharSet.Auto )]
> public static extern bool SetEnvironmentV ariable (string sName, string
> sValue);
>
> private DemoStruct ds;
> private IntPtr pGlobalText = IntPtr.Zero;
>
> void SimpleFunction( )
> {
> ds = new DemoStruct();
> ds.function1 = new DelFn1( MyFunction1 );
> ds.function2 = new DelFn2( MyFunction2 );
>
> // Allocate unmanaged memory the dll can read/write
> pGlobalText = Marshal.AllocHG lobal (5);
>
> lstrcpyA ( pGlobalText, "test" ); // write
>
> // pass pointer as hex string value
> SetEnvironmentV ariable("test",

pGlobalText.ToI nt32().ToString ("X") ); > }
>
> * After this function you can :
> - read from globaltext
> Console.WriteLi ne ( Marshal.PtrToSt ringAnsi( pGlobalText ) ); /// READ

> - write to globaltext
> lstrcpyA ( pGlobalText, text );

> - cleanup globaltext
> (only if dll doesn't need globaltext anymore)
> Marshal.FreeHGl obal( pGlobalText );


> HTH,


Believe me, it did. Thanks!
Brian


--
Brian
Nov 16 '05 #6
I've got two more questions, and *hopefully* that'll be all for a while.

First, I've got a character array (either signed or unsigned depending
on the usage) that will be passed to a callback. To complicate matters,
this character array is modifiable. I'm assuming that I should use define
my callback like:

public delegate void fn(ref IntPtr pData);

If correct, how do I manipulate the data passed to the callback? I've
tried accessing it like:

pData[0] = 230;

but this gives errors. I'd like to be able to modify the data directly if
needed. In some cases setting the pointer to a text message is preferred.

Second question: How are enumerated types stored memory-wise? I've got an
enumerated type that I pass to some of my callbacks. It's a fairly
straight-forward enum (i.e. starts with 0 and increments as would be
expected.) I can always use UInt32 if I need to.

Thanks,
Brian

Nov 16 '05 #7
Hi,

<Brian> wrote in message news:10******** *****@corp.supe rnews.com...
I've got two more questions, and *hopefully* that'll be all for a while.

First, I've got a character array (either signed or unsigned depending
on the usage) that will be passed to a callback. To complicate matters,
this character array is modifiable. I'm assuming that I should use define
my callback like:

public delegate void fn(ref IntPtr pData);
If the parameter was char** then this is fine.

If correct, how do I manipulate the data passed to the callback? I've
tried accessing it like:

pData[0] = 230;
You can use
- Marshal.WriteBy te(pData, idx, 230);
- Marshal.ReadByt e(pData, idx);

but this gives errors. I'd like to be able to modify the data directly if
needed. In some cases setting the pointer to a text message is preferred.
If you set a pointer to text or to anything you should allocate memory and
if you allocate memory you should free it not the dll, since this is a
callback, it might be difficult.

The problems start when eg. c# allocates memory and the dll must free it or
vice versa.

If you think it's possible to de-allocate it then you can use it:

pData = Marshal.StringT oHGlobalAnsi ("kkmkml");

You should call Marshal.FreeHGl obal(pData) at some time...

Second question: How are enumerated types stored memory-wise? I've got an
enumerated type that I pass to some of my callbacks. It's a fairly
straight-forward enum (i.e. starts with 0 and increments as would be
expected.) I can always use UInt32 if I need to.
I don't know. I would start with uint and if everything is fine you can try
using an enum.
HTH
greetings

Thanks,
Brian

Nov 16 '05 #8
Hi,
Hi, <Brian> wrote in message news:10******** *****@corp.supe rnews.com...
I've got two more questions, and *hopefully* that'll be all for a while.

First, I've got a character array (either signed or unsigned depending
on the usage) that will be passed to a callback. To complicate matters,
this character array is modifiable. I'm assuming that I should use define
my callback like:

public delegate void fn(ref IntPtr pData);
If the parameter was char** then this is fine.
No, it's just a char *. How will that affect the prototype?

If correct, how do I manipulate the data passed to the callback? I've
tried accessing it like:

pData[0] = 230;

You can use
- Marshal.WriteBy te(pData, idx, 230);
- Marshal.ReadByt e(pData, idx);
Hmmm. Seems a bit cumbersome. It's doubtful that individual bytes would
*need* to be changed, so I'll leave that up to my end user.

What about writing the whole thing out to file? How would I accomplish
that now that you know it's a char * instead of a char **?
If you set a pointer to text or to anything you should allocate memory and
if you allocate memory you should free it not the dll, since this is a
callback, it might be difficult. The problems start when eg. c# allocates memory and the dll must free it or
vice versa.
I was afraid you might say that. The pointer passed to the callback is
also used internally by the DLL for performance reasons. Of course, this
data cannot be modified by the DLL before the callback returns.
pData = Marshal.StringT oHGlobalAnsi ("kkmkml");
kkmkml? :)

I don't know. I would start with uint and if everything is fine you can try
using an enum.
Guess I'll find out the old-fashioned way. Gotta get my hammer ready.
HTH


Thanks. I appreciate your help. I'm understanding things much better
now.

Brian
Nov 16 '05 #9
Hi,

<Brian> wrote in message news:10******** *****@corp.supe rnews.com...
Hi,
Hi,
<Brian> wrote in message news:10******** *****@corp.supe rnews.com...
I've got two more questions, and *hopefully* that'll be all for a while.
First, I've got a character array (either signed or unsigned depending
on the usage) that will be passed to a callback. To complicate matters, this character array is modifiable. I'm assuming that I should use define my callback like:

public delegate void fn(ref IntPtr pData);
If the parameter was char** then this is fine.


No, it's just a char *. How will that affect the prototype?


Wel if it's just char* , then the callback function can't change the
pointer. You *can* change or read the data. The prototype should be just
IntPtr not ref IntPtr.

If correct, how do I manipulate the data passed to the callback? I've
tried accessing it like:

pData[0] = 230;
You can use
- Marshal.WriteBy te(pData, idx, 230);
- Marshal.ReadByt e(pData, idx);

This is still valid in case you need it.

Hmmm. Seems a bit cumbersome. It's doubtful that individual bytes would
*need* to be changed, so I'll leave that up to my end user.

What about writing the whole thing out to file? How would I accomplish
that now that you know it's a char * instead of a char **?
You can copy it into a string and write the string to a file :

string data = Marshal.PtrToSt ringAnsi( pData );
Stream s = File.OpenWrite( "test.txt" );
StreamWriter sw = new StreamWriter( s );
sw.Write ( data );
s.Close();

If you would know the size of the data then you could also put it inside a
byte[] and use a BinaryWriter :

byte [] data = new byte[size];
Marshal.Copy ( pData, data, 0, size );
Stream s = File.OpenWrite( "test.dat" );
BinaryWriter bw = new BinaryWriter( s );
bw.Write ( data );
s.Close();

If this isn't sufficient please ask again.
If you set a pointer to text or to anything you should allocate memory
and if you allocate memory you should free it not the dll, since this is a
callback, it might be difficult.

The problems start when eg. c# allocates memory and the dll must free it or vice versa.


I was afraid you might say that. The pointer passed to the callback is
also used internally by the DLL for performance reasons.
Of course, this
data cannot be modified by the DLL before the callback returns.
pData = Marshal.StringT oHGlobalAnsi ("kkmkml");
This is *no longer valid*, to be able to change a pointer you need a pointer
to pointer.

If you want to change the data you should use lstrcpyA, WriteByte or
Marshal.Copy.
I've already demonstrated lstrcpyA and WriteByte in earlier reply.
Here is a example where you use Marshal.Copy to change the data.

byte [] ToWriteData = new byte[size];
// fill ToWriteData
Marshal.Copy ( ToWriteData, 0, pData, size );

kkmkml? :)
I was in a hurry :)

I don't know. I would start with uint and if everything is fine you can
try using an enum.


Guess I'll find out the old-fashioned way. Gotta get my hammer ready.


Don't worry. Remember that you can always cast an enum to an int if you
want to play safe.

HTH,
greetings

HTH


Thanks. I appreciate your help. I'm understanding things much better
now.

Brian

Nov 16 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

22
1383
by: Brian | last post by:
I am very new to C# programming and have run into a problem. I apologize for the repost of this article. For some reason, my news reader attached it to an existing thread. First off, I have an SDK that I have written for C/C++ and would like to port it to C# if at all possible. Basically, I've got a structure that I need to pass to the C-style DLL (i.e. no mangled names - everything is __stdcall). This structure needs
25
1424
by: Brian | last post by:
I am very new to C# programming and have run into a problem. I apologize for the repost of this article. For some reason, my news reader attached it to an existing thread. First off, I have an SDK that I have written for C/C++ and would like to port it to C# if at all possible. Basically, I've got a structure that I need to pass to the C-style DLL (i.e. no mangled names - everything is __stdcall). This structure needs
0
9377
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10136
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9925
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9811
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8814
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7358
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6640
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5266
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
3
3509
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.