Pointers in C# to Retrieve Reference From DllImport Function

后端 未结 3 842
滥情空心
滥情空心 2021-01-23 01:12

I am referencing a DLL in my C# project as follows:

[DllImport(\"FeeCalculation.dll\", CallingConvention = CallingConvention.StdCall,
           CharSet = CharSe         


        
相关标签:
3条回答
  • 2021-01-23 01:50

    Edit: now that we have structures to work with, a better solution is possible. Just declare structs in C# that match your C++ structs, and use them in the extern declaration

    [StructLayout(LayoutKind.Sequential)]
    public struct feeAnswer {
       public uint    fee;
       public uint    tax1;
       public uint    tax2;
       public uint    tax3;
       public uint    tax4;
       public uint    surcharge1;
       public uint    surcharge2;
       public uint    validationFee;
       public uint    couponFee1;
       public uint    couponFee2;
       public uint    couponFee3;
       public uint    couponFee4;
       public ushort  dstay;       //Day Stay
       public ushort  mstay;       //Minute Stay
       };
    
      [StructLayout(LayoutKind.Sequential, Pack=1)]
      public struct feeRequest {
       public byte   day;
       public byte   month;
       public uint   year;   //2000 ~ 2099
       public byte   hour;
       public byte   minute;
       public byte   rate;
       public byte   validation;
       public byte   coupon1;
       public byte   coupon2;
       public byte   coupon3;
       public byte   coupon4;
       };
    
      [DllImport ("FeeCalculation.dll", CallingConvention = CallingConvention.StdCall,
                 CharSet = CharSet.Ansi)]
      public static extern void FeeCalculation (
              feeRequest cin,
              out feeAnswer cout,
               ...
    
    
    
            ....
    

    original answer (before we had structs) below


    It appears to me that these are not references to internal strings, but rather pointers to string buffers that will be filled in by the call. If you were returning string pointers, then these would be declared char** rather than char*.

    So I think these are just standard out parameters. There's just a lot of them. So your C# interop would look like this

    [DllImport("FeeCalculation.dll", CallingConvention = CallingConvention.StdCall,
               CharSet = CharSet.Ansi)]
    public static extern void FeeCalculation(string cin, 
            [MarshalAs(UnmanagedType.LPStr, SizeConst=100)]
            out string cout, 
            [MarshalAs(UnmanagedType.LPStr, SizeConst=100)]
            out string flimit,
    

    or this if your "strings" aren't really strings

    [DllImport("FeeCalculation.dll", CallingConvention = CallingConvention.StdCall,
               CharSet = CharSet.Ansi)]
    public static extern void FeeCalculation(string cin, 
            [MarshalAs(UnmanagedType.LPArray, SizeConst=100)]
            out byte[] cout, 
            [MarshalAs(UnmanagedType.LPArray, SizeConst=100)]
            out byte[] flimit,
            ....
    
    0 讨论(0)
  • 2021-01-23 01:50

    The char* parameters in this case are not strings but pointers to chunks of raw bytes representing the data. You should marshal your parameters as instances of the IntPtr type, in conjunction with Marshal.AllocHGlobal to create a chunk of memory and then Marshal.PtrToStructure to convert that block of memory into a usable .NET type.

    As an example:

    [StructLayout(LayoutKind.Sequential)]
    struct MyUnmanagedType
    {
        public int Foo;
        public char C;
    }
    
    IntPtr memory = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MyUnmanagedType)));
    
    try
    {
        FeeCalculation(memory);
    
        MyUnmanagedType result = (MyUnmanagedType)Marshal.PtrToStructure(
            memory, typeof(MyUnmanagedType));
    }
    finally
    {
        Marshal.FreeHGlobal(memory);
    }
    
    0 讨论(0)
  • 2021-01-23 02:07

    To answer your Edit, you need to create a struct, and then use the StructLayoutAttribute on the fields in order to make the byte order and padding the same as the original dll did.

    0 讨论(0)
提交回复
热议问题