Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.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#_.net_Marshalling - Fatal编程技术网

C#封送处理-获取C字符**的内容并转换为字节[]

C#封送处理-获取C字符**的内容并转换为字节[],c#,.net,marshalling,C#,.net,Marshalling,我有一个C DLL,其中有一个返回“char**”的函数。我需要将它传递到C#下的MemoryStream 如何处理这个问题 我已经试过了 [DllImport("ctf.dll")] public static extern long tts_sintetizaTexto_mm(long canal, string text, char* BuffVoice); 当我尝试在MemoryStream上使用BuffVoice时,它会产生编译错误 蒂亚, Nilo-巴西关于互操作映射的最新

我有一个C DLL,其中有一个返回“char**”的函数。我需要将它传递到C#下的MemoryStream

如何处理这个问题

我已经试过了

[DllImport("ctf.dll")]
    public static extern long tts_sintetizaTexto_mm(long canal, string text, char* BuffVoice);
当我尝试在MemoryStream上使用BuffVoice时,它会产生编译错误

蒂亚,
Nilo-巴西

关于互操作映射的最新文章:(虽然是关于Mono的,但当它们兼容时,它是关于.NET的)。 最常见的一点是直接从系统中marshall“in”字符串。具有MarshallAs属性的字符串用于精确映射,“out”字符串使用具有MarshallAs和预定义大小的StringBuilder

我自己也曾与PInvoke有过一些麻烦,这与你的问题很接近:

但您的示例不清楚:tts_sintetizaTexto_mm(长运河、字符串文本、字符*BuffVoice)

这里什么是来自C,什么是来自C#-string它是System.string还是std::string char*是什么意思?不安全的C字符(宽字符!)指针或仅C字符*(有符号!)字节缓冲区???-如果std::string-它与PInvoke不兼容-使用char*或wchar\u t*实现自己的C重载,如果是char*-请记住,它不是byte[],而byte[]是uchar*。。。如果是C#char*-记住C#char是16位的,所以有效的C类型应该是wchar#t或ushort。。。我们可以在哪里发送缓冲区大小以防止溢出?那么你刚才问的问题还有哪些呢

对于我的Expirence,虽然它不是来自属性,但更可控:使用Marshall.GlobalHAlloc和IntPtr作为互操作类型(对于任何xxxx*)


这里:您可以看到使用GCHandle的close示例,它几乎与关于互操作映射的最新文章相同(虽然它是关于Mono的,但是当它们兼容时,它是关于.NET的)。 最常见的一点是直接从系统中marshall“in”字符串。具有MarshallAs属性的字符串用于精确映射,“out”字符串使用具有MarshallAs和预定义大小的StringBuilder

我自己也曾与PInvoke有过一些麻烦,这与你的问题很接近:

但您的示例不清楚:tts_sintetizaTexto_mm(长运河、字符串文本、字符*BuffVoice)

这里什么是来自C,什么是来自C#-string它是System.string还是std::string char*是什么意思?不安全的C字符(宽字符!)指针或仅C字符*(有符号!)字节缓冲区???-如果std::string-它与PInvoke不兼容-使用char*或wchar\u t*实现自己的C重载,如果是char*-请记住,它不是byte[],而byte[]是uchar*。。。如果是C#char*-记住C#char是16位的,所以有效的C类型应该是wchar#t或ushort。。。我们可以在哪里发送缓冲区大小以防止溢出?那么你刚才问的问题还有哪些呢

对于我的Expirence,虽然它不是来自属性,但更可控:使用Marshall.GlobalHAlloc和IntPtr作为互操作类型(对于任何xxxx*)


这里:您可以看到带有GCHandle的close sample几乎是相同的

记住
char
在C中实际上是一个无符号字节。这意味着它实际上是
byte**
——它本身可以是两件事之一:指向数组的指针(
byte[]*
)或数组数组(
byte[][]

指向数组的指针 这种情况更有可能发生

[DllImport("ctf.dll")]
public static extern long tts_sintetizaTexto_mm(long canal, string text, ref byte[] BuffVoice);
如果这是一个Microsoft API,那么很有可能它就是这样工作的:

[DllImport("ctf.dll")]
private static extern long tts_sintetizaTexto_mm(long canal, string text, ref byte[] BuffVoice);

public byte[] SintetizaText(long canal, string text)
{
    // The first call requests the size of the memory that we need to allocate.
    byte[] buffer = null;
    var size = tts_sintetizaTexto_mm(canal, text, ref buffer);
    if (size <= 0) throw new Exception();

    // The second call actually does the work.
    buffer = new byte[(int)size];
    size = tts_sintetizaTexto_mm(canal, text, ref buffer);

    // size either holds a new size, or the result code.
    // size: Array.Resize(ref buffer, size);
    // result code: if (size != 0) throw new Exception();

    return buffer;
}

请记住,C中的char实际上是一个无符号字节。这意味着它实际上是
byte**
——它本身可以是两件事之一:指向数组的指针(
byte[]*
)或数组数组(
byte[][]

指向数组的指针 这种情况更有可能发生

[DllImport("ctf.dll")]
public static extern long tts_sintetizaTexto_mm(long canal, string text, ref byte[] BuffVoice);
如果这是一个Microsoft API,那么很有可能它就是这样工作的:

[DllImport("ctf.dll")]
private static extern long tts_sintetizaTexto_mm(long canal, string text, ref byte[] BuffVoice);

public byte[] SintetizaText(long canal, string text)
{
    // The first call requests the size of the memory that we need to allocate.
    byte[] buffer = null;
    var size = tts_sintetizaTexto_mm(canal, text, ref buffer);
    if (size <= 0) throw new Exception();

    // The second call actually does the work.
    buffer = new byte[(int)size];
    size = tts_sintetizaTexto_mm(canal, text, ref buffer);

    // size either holds a new size, or the result code.
    // size: Array.Resize(ref buffer, size);
    // result code: if (size != 0) throw new Exception();

    return buffer;
}

这不是C。请删除C标记。完成。但我已经标记为C,因为我的DLL是用C编写的。试着看这里@agent5566事实上,这与我需要的正好相反,但我会尝试用你的提示来做一些调整。谢谢。这无法直接封送,内存管理有一个严重的问题。您必须将最后一个参数声明为out IntPtr,然后使用Marshal.PtrToStringAnsi()恢复字符串。请确保编写一个调用此函数10亿次的单元测试,预计它会在内存不足错误时崩溃并死亡。这不是C。请删除C标记。完成。但我已经标记为C,因为我的DLL是用C编写的。试着看这里@agent5566事实上,这与我需要的正好相反,但我会尝试用你的提示来做一些调整。谢谢。这无法直接封送,内存管理有一个严重的问题。您必须将最后一个参数声明为out IntPtr,然后使用Marshal.PtrToStringAnsi()恢复字符串。一定要编写一个单元测试来调用这个函数10亿次,它预计会在内存不足的错误中死掉。这正是我需要的。谢谢!正是我需要的。谢谢!