Правильно ли я сортирую эту функцию C в C #? - PullRequest
2 голосов
/ 15 декабря 2010

В C # я пытаюсь вызвать следующий метод C:

// C code:
BOOL VstSetLineDetail(
   tVstHdl pDataHdl, // type is void*
   long pLineItemNo, 
   tVstTransType pTransType, // enum type
   tVstTransSubType pTransSubType, // enum type
   tVstTransCd pTransCd, // enum type
   char *pTransDate, 
   tVstTaxedGeo *pTaxedGeoFlag, // enum type
   double *pExtdAmt, 
   double *pTotalTax, 
   double *pCombRate, 
   char *pUserArea, 
   tVstTaxingJuris *pTaxingJuris, // enum type
   char *pCustExmtCertifNum, 
   char *pDivCd, 
   char *pStoreCd, 
   char *pGLAcct)

Я пишу это в C # следующим образом:

// C# code:
[DllImport(@"VertexNative\Vst.dll")]
public static extern bool VstSetLineDetail(
   [In]IntPtr dataHandle, 
   [In]long lineItemNumber, 
   [In]VstTransactionType transactionType, // an enum I defined in C#
   [In]VstTransactionSubtype transactionSubtype, // C# enum
   [In]VstTransactionCode transactionCode, // C# enum
   [In]string transactionDate, 
   [In]ref VstTaxedGeo taxedGeo, // C# enum
   [In]ref double totalAmount, 
   [In]ref double totalTax, 
   [In]ref double combinedTaxRate, 
   [In]string userArea, 
   [In]ref VstTaxingJurisdiction jurisdiction, // C# enum
   [In]string exceptionCertificate, 
   [In]string divisionCode, 
   [In]string storeCode, 
   [In]string generalLedgerAccount);

Вызов его всегда вызывает исключение System.AccessViolationException. Я пробовал много комбинаций значений при вызове функции, но не получил лучших результатов. Может кто-нибудь сказать мне, если это выглядит, как будто я правильно сортирую типы данных?

Было бы замечательно, если бы у меня был доступ к исходному коду C, чтобы я мог отлаживать, но это сторонний набор библиотек DLL. Я вижу только заголовочные файлы.

Перечисления в C:

typedef enum
{
    eVstTransTypeIgnore = 99,   /* Means ignore this parameter */
    eVstTransTypeSale = 0,
    eVstTransTypePurchase,
    eVstTransTypeService,
    eVstTransTypeRentalLease,
    eVstTransTypeNumElems,
    eVstTransTypeFirstElem = eVstTransTypeSale
} tVstTransType;

typedef enum
{
    eVstTransSubTypeIgnore = 99,    /* Means ignore this parameter */
    eVstTransSubTypeNone = 0,
    eVstTransSubTypeProperty,
    eVstTransSubTypeFreight,
    eVstTransSubTypeService,
    eVstTransSubTypeRentalLease,
    eVstTransSubTypeExpense,
    eVstTransSubTypeMisc,
    eVstTransSubTypeNumElems,
    eVstTransSubTypeFirstElem = eVstTransSubTypeNone
} tVstTransSubType;

typedef enum
{
    eVstTransCdIgnore = 99, /* Means ignore this parameter */
    eVstTransCdNormal = 0,
    eVstTransCdAdjustment,
    eVstTransCdTaxOnlyDebit,
    eVstTransCdTaxOnlyCredit,
    eVstTransCdDistributeRate,
    eVstTransCdDistributeTax,
    eVstTransCdNumElems,
    eVstTransCdFirstElem = eVstTransCdNormal
} tVstTransCd;

typedef enum
{
    eVstTaxedGeoNone = 0,
    eVstTaxedGeoDetermine,
    eVstTaxedGeoShipTo,
    eVstTaxedGeoShipFrom,
    eVstTaxedGeoOrderAccept,
    eVstTaxedGeoNumElems,
    eVstTaxedGeoFirstElem = eVstTaxedGeoNone
} tVstTaxedGeo;

typedef enum {  
    eVstTaxingJurisPrimary,
    eVstTaxingJurisAddtl,
    eVstTaxingJurisNumElems,
    eVstTaxingJurisFirstElem = eVstTaxingJurisPrimary
} tVstTaxingJuris;

И я определил их в C # как:

public enum VstTransactionType
{
      Sale,
      Purchase,
      Service,
      RentalLease,
      Ignore = 99
}

public enum VstTransactionSubtype
{
     None,
     Property,
     Freight,
     Service,
     RentalLease,
     Expense,
     Misc,
     Ignore = 99
}

public enum VstTransactionCode
{
     Normal,
     Adjustment,
     TaxOnlyDebit,
     TaxOnlyCredit,
     DistributeRate,
     DistributeTax,
     Ignore = 99
}

public enum VstTaxedGeo
{
     None,
     Determine,
     ShipTo,
     ShipFrom,
     OrderAccept
}

public enum VstTaxingJurisdiction
{
      Primary,
      Additional
}

1 Ответ

4 голосов
/ 15 декабря 2010

Нет, это не правильно, потому что long в C - это не 8 байтов, как в C # (часто это 4 байта).Кроме того, char* не обязательно string, потому что string s предназначены для того, чтобы быть неизменными, и вы можете только безопасно назначить их для const char*, поскольку только это может гарантировать, что код C не будетизменить их.Если вам нужно сделать их изменяемыми, используйте StringBuilder вместо string и используйте [MarshalAs(UnmanagedType.LPTStr)] или подобное.

...