Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 调用更改c中传递参数的c dll函数#_C#_C_Dll_Pinvoke - Fatal编程技术网

C# 调用更改c中传递参数的c dll函数#

C# 调用更改c中传递参数的c dll函数#,c#,c,dll,pinvoke,C#,C,Dll,Pinvoke,我正在将一个C#字符串传递给C dll函数,该函数假定对其进行加密。不幸的是,它什么也做不了。调用函数后,字符串仍保持不变 C功能: #include <stdio.h> #include <stdlib.h> extern "C"{ __declspec(dllexport) void Encrypt( char *plainText,long height,long inputLength) { unsig

我正在将一个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; 


    }

     }
     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 ===");
           }
并调用该函数:

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


    }

     }
     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 ===");
           }

调用后,纯文本不会更改。

这是意料之中的。您正在编组数据,但没有编组数据。这是string类型参数的行为。您需要使用StringBuilder从本机代码封送文本

另外,C长是64位,而C++长是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(纯文本)的malloc调用。这是指针的大小。您需要传递缓冲区的长度inputLength。在尝试互操作之前,您应该首先调试代码。

我在您建议使用ref关键字的同时发布了一个答案,您指出这将不起作用。您是否愿意详细说明这种方法失败的原因?@Fopedush因为它映射到char**而不是char*,谢谢您的回答。我在C代码中加入了一些printf调用。事实证明,它使用C#字符串没有任何问题(如我发布的代码中所实现的)和高度,但inputLength等于0。我试图用硬编码的int(例如4)来调用函数,但它仍然等于0。有什么建议吗?你仔细看过我的答案了吗?特别是关于C长不匹配C++长的部分。根据我的最后一段,您还需要调试本机代码。那么,您现在在我的回答中使用了pinvoke?你是否已经修复了C++代码?在进行互操作之前,您必须对其进行排序。注意,malloc(sizeof(明文))将只分配4或8个字节(取决于您构建的是32位还是64位软件)。按照@elgonzo所说的,您可能需要
malloc(strlen(明文))
@MarkkuK。不,它是malloc(inputLength)