Domanda

Io sono il riferimento a una DLL nel mio progetto C# come segue:

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

Il FeeCalculation funzione viene esportato come segue DLL:

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

La DLL funzione restituisce un riferimento interno di strutture a forma di char * quindi, se si dovesse fare riferimento a questa DLL in C++, si deve fare il calcolo e il ottenere il restituiti strutture:

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

Ora, come faccio a recuperare quei valori che sono tornato da riferimento per l'utilizzo di C#?Significato, come faccio a fare la stessa cosa in C# per ottenere il restituiti strutture per ottenere il mio restituito calcolo?So che ho bisogno di creare un sicuro metodo, ma io sono poco chiare su come trattare con gli indirizzi di memoria in C# come in C++.

Edit:Al di sotto di membri, di utilizzare IntPtr ma come si fa luogo, in identica struttura così i campi della struttura è possibile fare riferimento?

Edit:Qui è tornato struttura che mi interessa (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

};

Qui è l' (cin) che vorrei passare insieme con le altre strutture (che sono pari a zero byte al momento, voglio ottenere questo lavoro prima, poi mi attuare il resto):

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;

};
È stato utile?

Soluzione

Edit:ora che abbiamo strutture a lavorare, una soluzione migliore è possibile.Dichiarare nelle strutture in C# che corrispondono ai tuoi C++ le strutture da utilizzare per la dichiarazione extern

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



        ....

originale risposta (prima avevamo struct) qui sotto


A me sembra che questi non sono i riferimenti interni corde, ma piuttosto puntatori a stringa buffer che sarà riempito dalla chiamata.Se si fosse di ritorno i puntatori di stringa, quindi questi sarebbero dichiarati char** piuttosto che char*.

Quindi penso che questi sono solo standard parametri.C'è solo un sacco di loro.Così il C# interoperabilità sarebbe simile a questa

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

o questo se il tuo "stringhe" non sono realmente stringhe

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

Altri suggerimenti

I char * parametri in questo caso non sono stringhe, ma i puntatori ai blocchi di byte non elaborati che rappresentano i dati. Si dovrebbe schierare i parametri come le istanze del tipo IntPtr, in collaborazione con Marshal.AllocHGlobal per creare un pezzo di memoria e quindi Marshal.PtrToStructure convertire tale blocco di memoria in un tipo NET utilizzabili.

Per fare un esempio:

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

Per rispondere alla tua Edit, è necessario creare una struttura, e quindi utilizzare il StructLayoutAttribute sui campi al fine di rendere l'ordine dei byte e imbottitura lo stesso come la dll originale ha fatto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top