2013-10-28 46 views
2

我tyring將C#字符串傳遞給C dll函數,它假設加密它。不幸的是,它根本就沒有。調用該函數後,該字符串仍然相同。調用c改變傳遞參數在C中的dll函數#

C函數:

#include <stdio.h> 
    #include <stdlib.h> 
    extern "C"{ 
    __declspec(dllexport) void Encrypt(char *plainText,long height,long inputLength) 
    { 
     unsigned char *encryptedText=(unsigned char*)malloc(sizeof(plainText)); 
     unsigned char **cipherArray; 


     cipherArray=(unsigned char**)malloc(height*sizeof(unsigned char *)); 
     for(long i=0; i<height; i++) 
     { 
      cipherArray[i]=(unsigned char*)malloc(inputLength*sizeof(char)); 
      for (long j=0; j<inputLength ; j++) 
       cipherArray[i][j]='#'; 
     } 






     bool addRow=true; 
     long row=0; 
     long column = 0; 
     long arrayIterator = 0; 
     while(arrayIterator<inputLength){ 
      cipherArray[row][column] = plainText[arrayIterator]; 

        column++; 
        if(addRow)row++; 
        else row--; 
        if (row >= height) 
        { 
         row--; 
         row--; 
         addRow=false; 
        } 
        else if (row < 0) 
        { 
         row++; 
         row++; 
         addRow = true; 
        } 
        arrayIterator++; 
     } 



     long iterator=0; 
     for (long i=0; i< height; i++) 
      for(long j=0; j<inputLength;j++){ 
       if(cipherArray[i][j]!='#'){ 
        encryptedText[iterator]=cipherArray[i][j]; 
        iterator++; 
       } 
      } 

     long j=0; 
     while(j<inputLength){ 
      plainText[j]=encryptedText[j]; 
      printf("%c",encryptedText[j]); 
      j++; 
     } 

     for(long i=0; i<height; i++) 
      free(cipherArray[i]); 
     free(cipherArray); 
     cipherArray = NULL; 


    } 

    } 

含C#類:

namespace RailFenceCipher 
    { 
     public class CCipher 
     { 
      [DllImport("Win32Project3.dll", EntryPoint = "Encrypt", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] 
      public static extern void Encrypt([MarshalAs(UnmanagedType.LPStr)] string plainText, long height, long inputLength); 



     } 
    } 

,並呼籲功能:

 private void cipherC() 
      { 

       string plainText = this.fileInput; 
       Console.WriteLine("=== C# test, using IntPtr and Marshal ==="); 
       CCipher.dllprint(); 
       CCipher.Encrypt(plainText, this.height, this.fileInput.Length); 
       this.fileOutputC = plainText; 
       Console.WriteLine("=== END ==="); 
      } 
呼叫後

,明文沒有改變。

+0

請注意,malloc(sizeof(plainText))只會分配4或8個字節(取決於您構建的是32位還是64位軟件)。 – elgonzo

+0

繼續了@elgonzo說的話,你可能想'malloc(strlen(plainText))' –

+0

@MarkkuK。不,它是malloc(inputLength) –

回答

2

這是可以預料的。你正在編組數據,但沒有出。這是字符串類型參數的行爲。您需要使用StringBuilder才能從本機代碼中封送文本。

另外,C#long是64位,但C++ long在32位。您PInvoke的應該是:

[DllImport("Win32Project3.dll", CallingConvention = CallingConvention.Cdecl, 
    CharSet = CharSet.Ansi)] 
public static extern void Encrypt(StringBuilder plainText, 
    int height, int inputLength); 

而且你需要確保的是,StringBuilder實例您傳遞的容量足以要返回的文本。

也許更大的問題是你的C++代碼被破壞了。至少,您需要修復接收sizeof(plainText)的malloc調用。這是一個指針的大小。您需要傳遞緩衝區的長度inputLength。在嘗試互操作之前,您應該首先調試該代碼。

+0

我發佈了一個答案,大約是在你建議使用ref關鍵字的同時,而不是你指出的那樣。你是否想詳細說明爲什麼這種方法會失敗? – Fopedush

+1

@Fopedush因爲它映射到char **而不是char * –

+0

感謝您的答覆。我用C代碼放了一些printf調用。事實證明,它沒有任何問題的C#字符串(在我發佈的代碼中實現)和heigth,但inputLength等於0.我試圖用硬編碼int調用函數(例如4),但它仍然等於0.任何建議? – sliwkacz