none
How create c++ struct in c# (pointer to function)?

    Question

  • Hello

    I have "small" problem. I must create struct like this:
    [C++ code]
    typedef struct

    {

    tTYPE_TRANSL_FUNC TypeTranslFuncPtr ;

    LPVOID ParamValuePtr ;

    } tEXTERNAL_NUMERIC;

    where tTYPE_TRANSL_FUNC function is typedef int ( *tTYPE_TRANSL_FUNC )( LPVOID, char * );

    This function take 2 param. First is any type, and second is string. Function convert first param to char* (second param).

    A wrote in C# code like this:

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
     public struct tEXTERNAL_NUMERIC
        {
            [MarshalAs(UnmanagedType.FunctionPtr)]
            public tTYPE_TRANSL_FUNCDelegate TypeTranslFuncPtr;     
            [MarshalAs(UnmanagedType.AsAny)]
            public IntPtr ParamValuePtr;  
        };
        public delegate int tTYPE_TRANSL_FUNCDelegate(IntPtr var1, StringBuilder var2);

    but this not work. What is wrong in this code? Please help....

    • Edited by Donu pl Tuesday, September 01, 2009 12:56 PM
    Thursday, August 20, 2009 12:00 PM

Answers

  • Drop the [MarshalAs] attributes, the default marshaling is already correct.  The StringBuilder argument for the function pointer cannot work, it won't be initialized properly.  If the native code simply passes a string, declare it as string.  If it passes a pointer to a buffer that the callee needs to fill with a string then you must declare it as IntPtr and marshal the string yourself.  Use Marshal.StringToHGlobalAnsi, then Marshal.Copy, then Marshal.FreeHGlobal
    Hans Passant.
    • Marked as answer by Harry Zhu Thursday, August 27, 2009 2:06 AM
    Thursday, August 20, 2009 4:31 PM

All replies

  • Drop the [MarshalAs] attributes, the default marshaling is already correct.  The StringBuilder argument for the function pointer cannot work, it won't be initialized properly.  If the native code simply passes a string, declare it as string.  If it passes a pointer to a buffer that the callee needs to fill with a string then you must declare it as IntPtr and marshal the string yourself.  Use Marshal.StringToHGlobalAnsi, then Marshal.Copy, then Marshal.FreeHGlobal
    Hans Passant.
    • Marked as answer by Harry Zhu Thursday, August 27, 2009 2:06 AM
    Thursday, August 20, 2009 4:31 PM
  • Drop the [MarshalAs] attributes, the default marshaling is already correct.  The StringBuilder argument for the function pointer cannot work, it won't be initialized properly.  If the native code simply passes a string, declare it as string.  If it passes a pointer to a buffer that the callee needs to fill with a string then you must declare it as IntPtr and marshal the string yourself.  Use Marshal.StringToHGlobalAnsi, then Marshal.Copy, then Marshal.FreeHGlobal
    Hans Passant.
    Thanks for answer

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
     public struct tEXTERNAL_NUMERIC
        {
            public tTYPE_TRANSL_FUNCDelegate TypeTranslFuncPtr;     
            public IntPtr ParamValuePtr;  
        };
        public delegate int tTYPE_TRANSL_FUNCDelegate(IntPtr var1, string var2);


    Now this is good?
    Tuesday, September 01, 2009 1:01 PM
  • Don't ask me.  It's good when it works.

    Hans Passant.
    Tuesday, September 01, 2009 1:05 PM
  • A ask because... When I build and exec program work, but... This struct is pass to fiscal printer to create sam report. When I want to print somthing and I pass this struct, printer write interface error. I don't know that this error is generated because struct or somthing else.

    Thangs for help anyway
    Thursday, September 03, 2009 6:39 AM