0

C#アプリケーションでC言語で書かれた関数を使いたい。関数は dll ファイルにエクスポートされます。C 関数コード:

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


        cipherArray=(char**)malloc(height*sizeof(char *));
        for(long i=0; i<height; i++)
        {
            cipherArray[i]=(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++;
        }
    }

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

return encryptedText;
    }

C# アプリでは、この関数を使用するクラスを作成しました。

namespace RailFenceCipher
{
public class CCipher
   {
     [DllImport("CCipher.dll", CharSet = CharSet.Unicode)]
        unsafe public static extern char* Encrypt(char[] plainText, int height, long inputLength);

    }
}

ここが難しいところです... C 関数は char* オブジェクト (char 配列) を返します。私の質問は、関数の結果を C# 文字列に割り当てるにはどうすればよいですか?

今まで自力でなんとかしようとしていたのですが、うまくいきません...

dll 関数を呼び出します。

private void cipherC()
        {
            this.fileOutputC = "";
            unsafe
            {
                string cEncrypted =  new string(((CCipher.Encrypt(this.fileInput.ToCharArray(), this.height,fileInput.Length))));
             this.fileOutputC = cEncrypted;
            }
     }

事前に助けてくれてありがとう!

編集:

コードを次のように再編成しました。

dll の C コード:

    struct Wrapper{
        unsigned char* plainText;
        int height;
        long inputLength;
        unsigned char* result;
    };
    void Encrypt(unsigned char plainText[],int height,long inputLength,unsigned char result[])
    {
        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){
            result[j]=encryptedText[j];
            j++;
        }

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


    }

    extern "C" __declspec(dllexport) void CreateCWrapper(struct Wrapper **myWrapper,string plainText, long height, string result,long inputLength){


        *myWrapper=(struct Wrapper*)malloc(sizeof(struct Wrapper));
        (*myWrapper)->height = height;
        (*myWrapper)->inputLength= inputLength;
        (*myWrapper)->plainText= (unsigned char*)malloc(inputLength * sizeof(char));
         if ((*myWrapper)->plainText != NULL)
          for (long i = 0; i < inputLength; ++i)
              (*myWrapper)->plainText[i] = plainText[i];
        (*myWrapper)->result= (unsigned char*)malloc(inputLength * sizeof(char));



    }


    extern "C" __declspec(dllexport) void EncryptWithWrapper(Wrapper *myWrapper){
        unsigned char *table=(unsigned char*)malloc(sizeof(char)*myWrapper->inputLength);
        for(long i=0;i<myWrapper->inputLength;i++){
            table[i]=myWrapper->plainText[i];
        }
        unsigned char *res=(unsigned char*)malloc(sizeof(char)*myWrapper->inputLength);
        Encrypt(table,myWrapper->height,myWrapper->inputLength,res);
        for(long i=0;i<myWrapper->inputLength;i++){
            myWrapper->result[i]=res[i];

        }
        free(table);
        free(res);
    }

    extern "C" __declspec(dllexport) string getStrResultFromWrapper(Wrapper *myWrapper){
        string stringres;
        for(long i=0;i<myWrapper->inputLength;i++){
            stringres+=myWrapper->result[i];
        }
        return stringres;
    }

C# クラス:

    public class CCipher
        {
            [StructLayout(LayoutKind.Sequential)]
            public struct Wrapper
            {
                public IntPtr plainText;
                public int height;
                public IntPtr inputLength;
                public string result;
            }

            [DllImport("CCipher.dll")]
            public static extern void CreateCWrapper(out IntPtr myWrapper, string plainText, long height, string result, long inputLength);

            [DllImport("CCipher.dll")]
            public static extern void EncryptWithWrapper(IntPtr myWrapper);

            [DllImport("CCipher.dll")]
            public static extern string getStrResultFromWrapper(IntPtr myWrapper);
       }

および呼び出し関数:

       private void cipherC()
               {

                   IntPtr myWrapper;
                   CCipher.CreateCWrapper(out myWrapper, this.fileInput, this.height, this.fileOutputC, this.fileInput.Length);
                   CCipher.EncryptWithWrapper(myWrapper);

                   CCipher.Wrapper dataWrapper=(CCipher.Wrapper) Marshal.PtrToStructure(myWrapper,typeof(CCipher.Wrapper));
               }

問題は、次の呼び出し時です。

   CCipher.CreateCWrapper(out myWrapper, this.fileInput, this.height, this.fileOutputC, this.fileInput.Length);

アプリが停止するだけです。ヒントはありますか?

4

0 に答える 0