Frage

Ich Bezugnahme auf eine DLL in meinem C # Projekt wie folgt:

[DllImport("FeeCalculation.dll", CallingConvention = CallingConvention.StdCall,
           CharSet = CharSet.Ansi)]

        public static extern void FeeCalculation(string cin, string cout, string flimit,
            string frate, string fwindow, string fincrement, string fbird, 
            string fparameter, string fvalidation, string fcoupon);

Die FeeCalculation Funktion exportiert wird, wie in der DLL folgt:

extern "C" __declspec(dllexport) void __stdcall FeeCalculation(char *cin, 
char *cout, char *flimit, char *frate,
char *fwindow, char *fincrement, char *fbird,
char *fparameter, char *fvalidation, char *fcoupon);

Die DLL-Funktion gibt einen Verweis auf es interne Strukturen in Form von char * so, wenn Sie diese DLL in C ++ verweisen wären, würden Sie die im Anschluss an die Berechnung zu tun, und die zurückgegebenen Strukturen erhalten:

FeeCalculation(buff, (char *)&fans, (char *)fl, (char *)ft, (char *)fw, (char *)fi, (char *)fe, (char *)&fm, (char *)val, (char *)cpn);

Nun, wie rufe ich die Werte, die durch Bezugnahme mit C # zurückgegeben werden? Das heißt, wie kann ich das gleiche tun in C # die zurückgegebenen Strukturen zu bekommen meine zurück Berechnung zu bekommen? Ich weiß, ich brauche eine unsichere Methode zu schaffen, aber ich bin unklar, wie mit den Speicheradressen in C # zu tun, wie Sie es in C ++.

Edit:? Im Folgenden Zustand IntPtr zu verwenden, aber wie stellen Sie in identische Struktur, so dass die Felder der Struktur verwiesen werden können

Edit: Hier ist die zurückgegebene Struktur, dass ich bin an (cout):

struct feeAnswer {


    unsigned int    fee;

    unsigned int    tax1;

    unsigned int    tax2;

    unsigned int    tax3;

    unsigned int    tax4;

    unsigned int    surcharge1;

    unsigned int    surcharge2;

    unsigned int    validationFee;

    unsigned int    couponFee1;

    unsigned int    couponFee2;

    unsigned int    couponFee3;

    unsigned int    couponFee4;

    unsigned short int dstay;       //Day Stay

    unsigned short int mstay;       //Minute Stay

};

Hier ist die (cin), dass ich mit anderen Strukturen passieren entlang würde (sie sind Null-Byte in dem Moment, ich will dieses erhalten zuerst zu arbeiten, dann werde ich den Rest implementieren):

struct feeRequest {

    unsigned char   day;

    unsigned char   month;

    unsigned int    year;   //2000 ~ 2099



    unsigned char   hour;

    unsigned char   minute;

    unsigned char   rate;

    unsigned char   validation;



    unsigned char   coupon1;

    unsigned char   coupon2;

    unsigned char   coupon3;

    unsigned char   coupon4;

};
War es hilfreich?

Lösung

Edit: jetzt, wo wir haben Strukturen zur Arbeit mit, eine bessere Lösung ist möglich. deklarieren nur structs in C #, dass Ihre C ++ structs entsprechen, und sie in der extern-Deklaration verwenden

[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-Antwort (bevor wir structs hatten) unter


Es scheint mir, dass diese nicht Verweise auf interne Strings, sondern Zeiger auf String-Puffer, die durch den Aufruf in gefüllt werden. Wenn Sie waren Rückkehr string Zeiger, dann würden diese eher erklärt char** werden als char*.

Also ich denke, das sind nur Standard-out-Parameter. Es gibt nur eine Menge von ihnen. So C # Interop würde wie folgt aussehen

[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,

oder diese Option, wenn Ihre "Strings" sind nicht wirklich 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,
        ....

Andere Tipps

Die char * Parameter sind in diesem Fall keine Strings, sondern Zeiger auf Stücke von rohem Bytes, die die Daten darstellen. Sie sollten Ihre Parameter als Instanzen des IntPtr-Typs in Verbindung mit Marshal.AllocHGlobal Marschall einen Teil des Speichers zu erstellen und dann Marshal.PtrToStructure dass Speicherblock in einen nutzbaren .NET-Typ zu konvertieren.

Als Beispiel:

[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);
}

Ihre bearbeiten beantworten, müssen Sie eine Struktur schaffen, und verwenden Sie dann die StructLayoutAttribute auf den Feldern, um tat die Byte-Reihenfolge und Klotzen des gleiches wie das Original-dLL zu machen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top