Re: Help please with pointers to callbacks in structs

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

Brian
Date: 04/08/04


Date: Thu, 08 Apr 2004 00:59:18 -0000

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 <someone@someone.com> wrote:
> Hi,
> see inline;

> <Brian> wrote in message news:1078e5bgehc4q20@corp.supernews.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
>> SetEnvironmentVariable 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 _toPassAsArgumentStruct
>> {
>> int a;
>> int b;
>> double c;
>> } TO_PASS_AS_ARGUMENT;

> In c#:

> [StructLayout(StructLayout.Sequential)]
> 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_PASS_AS_ARGUMENT *structure);

> Declare a delegate for each callback:
> public delegate bool DelFn1(uint i, IntPtr pPath, uint pathLength);
> public delegate bool DelFn2(ref ToPassAsArgStruct structure);

>>
>>
>> typedef struct _demoStruct
>> {
>> FnPtr1 function1;
>> FnPtr2 function2;
>> } DEMOSTRUCT;

> In c#: (use the delegates)

> [StructLayout(StructLayout.Sequential)]
> public struct DemoStruct
> {
> public DelFn1 function1;
> public DelFn2 function2;
> }

>>
>> // MyFunction1 and MyFunction2 are called by the DLL
>>
>> BOOL MyFunction1(DWORD i, char *path, DWORD pathLength)
>> {
>> strcpy(path, "unknown");
>> return TRUE;
>> }

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

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

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

> private bool MyFunction2(ref ToPassAsArgStruct 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);
>>
>> SetEnvironmentVariable("test", text);

> [DllImport("kernel32.dll",CharSet=CharSet.Auto)]
> public static extern bool SetEnvironmentVariable (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.AllocHGlobal (5);

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

> // pass pointer as hex string value
> SetEnvironmentVariable("test", pGlobalText.ToInt32().ToString("X") );
> }

> * After this function you can :
> - read from globaltext
> Console.WriteLine ( Marshal.PtrToStringAnsi( pGlobalText ) ); /// READ

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

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

> HTH,
> greetings

>>
>>
>> }
>> --
>>
>> TIA,
>> Brian
>>



Relevant Pages

  • Re: Explicit Linking of DLLs in VB.net
    ... yes this technique will only work on managed assemblys (exe or dll) ... "YourObject" is a form and is limited to the form methods. ... Wel implement propertys, methods, events in your interface and start ... Public Shared Function LoadMeByName(ByVal vstrAssemblyName As String, ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Explicit Linking of DLLs in VB.net (attn Michel or any others)
    ... loads the dll and finds a form in the dll. ... Dim extForm As Form = extAssembly.CreateInstance("test.entry", ... Wel implement propertys, methods, events in your interface and start ... Public Shared Function LoadMeByName(ByVal vstrAssemblyName As String, ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Access crashes when calling DLL function.
    ... I have started bypassing code in the form to find the problem. ... are local String variables. ... I then built a simple input form (in the same mdb) that calls the crashing ... functions from a DLL they provide. ...
    (microsoft.public.access.modulesdaovba)
  • Re: Populating CString in Win32 dll interface that accepts LPCTSTR
    ... ReleaseBuffer() if I actually modify the buffer after GetBuffer is called ... But the OP wanted the string to be "populated" by the DLL. ... Unicode or ANSI string, but the DLL might think it is a non-const pointer to an ANSI ...
    (microsoft.public.vc.mfc)
  • Re: DLL with string params callable via D4 and VB
    ... > I have a DLL written in D6 that uses ShortStrings as parameters. ... I can't get beyond Delphi to ... > Is there any guidance you could give in regards to passing string ... written in order to be used by EXCEL 97 VBA. ...
    (borland.public.delphi.language.objectpascal)