Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.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 我有一个C++项目,其中我必须把一些变量从C++返回到C._C#_C++ - Fatal编程技术网

C# 返回C++字符到C 我有一个C++项目,其中我必须把一些变量从C++返回到C.

C# 返回C++字符到C 我有一个C++项目,其中我必须把一些变量从C++返回到C.,c#,c++,C#,C++,这些字符变量位于主程序中: 字符test1[MAX_Q_LEN],test2[MAX_Q_LEN],test3[MAX_Q_LEN] 当我在C程序中处理完这些变量后,我必须在C程序中返回这些变量的值 ReturnChar.h ReturnChar.cpp 测试导入C 我尝试了上述方法,但无法找到如何返回上述char值。此外,这不应该是一个独立的函数,因为只有在执行main之后才能获取值,main将在这些变量中提供正确的值 有什么建议?我将建议一个解决方案,该解决方案要求您将功能签名更改为: ex

这些字符变量位于主程序中:

字符test1[MAX_Q_LEN],test2[MAX_Q_LEN],test3[MAX_Q_LEN]

当我在C程序中处理完这些变量后,我必须在C程序中返回这些变量的值

ReturnChar.h

ReturnChar.cpp

测试导入C

我尝试了上述方法,但无法找到如何返回上述char值。此外,这不应该是一个独立的函数,因为只有在执行main之后才能获取值,main将在这些变量中提供正确的值


有什么建议?

我将建议一个解决方案,该解决方案要求您将功能签名更改为:

extern "C" int __cdecl testString(char *output, int outputSize);
也就是说,将分配的缓冲区作为第一个参数传递给将保存输出的函数,并将缓冲区的大小作为第二个参数传递

请注意,我提到函数的返回类型为int。这是因为您可以从函数返回输出的实际大小,调用方可以解释此值以确认outputSize值足够大,可以容纳输出字符串。例如,您可以将testString实现为:

并称之为:

private static string ReturnSomething()
{
   int bufferSize = 100;
   StringBuilder buffer= new StringBuilder(bufferSize);
   int outputSize = TestImport.testString(buffer, bufferSize);
   if ( outputSize < bufferSize )  //output bufferSize was sufficient
   {
        return buffer.ToString();
   }
   else //output bufferSize was insufficient 
   {
        //retry!
        bufferSize = outputSize;
        buffer = new StringBuilder(bufferSize); //reallocate!
        outputSize = TestImport.testString(buffer, bufferSize); 
        if ( outputSize <= bufferSize )
             return buffer.ToString();
        else
        {
            throw new Exception("PANIC");
        }
   }
}

我将建议一种解决方案,要求您将函数签名更改为:

extern "C" int __cdecl testString(char *output, int outputSize);
也就是说,将分配的缓冲区作为第一个参数传递给将保存输出的函数,并将缓冲区的大小作为第二个参数传递

请注意,我提到函数的返回类型为int。这是因为您可以从函数返回输出的实际大小,调用方可以解释此值以确认outputSize值足够大,可以容纳输出字符串。例如,您可以将testString实现为:

并称之为:

private static string ReturnSomething()
{
   int bufferSize = 100;
   StringBuilder buffer= new StringBuilder(bufferSize);
   int outputSize = TestImport.testString(buffer, bufferSize);
   if ( outputSize < bufferSize )  //output bufferSize was sufficient
   {
        return buffer.ToString();
   }
   else //output bufferSize was insufficient 
   {
        //retry!
        bufferSize = outputSize;
        buffer = new StringBuilder(bufferSize); //reallocate!
        outputSize = TestImport.testString(buffer, bufferSize); 
        if ( outputSize <= bufferSize )
             return buffer.ToString();
        else
        {
            throw new Exception("PANIC");
        }
   }
}

<>我不是很大的C++规范,但在C++中使用BSTR可能是
_bstr_t text("saasas");
return text.Detach();
对于c参数

[MarshalAs(UnmanagedType.BStr)] 

或将StringBuilder传递给C++ C++ FUNC,但预分配容量

< P>我不是很大的C++规范,但在C++

中可能使用BSTR
_bstr_t text("saasas");
return text.Detach();
对于c参数

[MarshalAs(UnmanagedType.BStr)] 

或将StringBuilder传递给C++的FUNC,并具有预先分配的容量

,因为我记得CLR将使用MalSal.FrEcOtaskMeM方法来释放字符串,在这种情况下,所以CoTaskMemAlloc应该被用来分配C++边新的可以在我们的情况下实现它自己,所以管理侧不能解除我的权限吗?@纳瓦兹:我试着改变StringBuilder,但是它没有给我任何输出。两者都没有引发任何异常/错误。我的完整代码:C文件:,reutnhar.cpp,ReturnChar.h@Nawaz:Two-ways。1调用者分配,这个方法被大多数WIn32 API使用,并且非常容易在两端都得到正确的结果。2商定一个分配器。例如,丹尼斯克的回答同意函数将使用SysLaScript,调用方P/Unjk必须使用SysFielScand,因为这些是每个BSTR使用的函数。@纳瓦兹:用.NET调用方和C++ CALLY,看起来像StrugBuudRead结果=新的StrugBueDeL1000;cppfuncresult,result.Length;C++函数将是空的CPPPRANCHARAR*OUTIB BUFF,int OutuBufl长度;一个简单的例子是Win32函数GetSystemDirectory。@Nawaz:这实际上是一个inout参数,正是它的作用。调用方在调用之前设置缓冲区,因此函数有内存可使用。我记得CLR在这种情况下将使用Marshal.FreeCoTaskMem方法取消分配字符串,所以CoTaskMemAlloc应该被用来分配C++边新的可以在我们的情况下实现它自己,所以管理侧不能解除我的权限吗?@纳瓦兹:我试着改变StringBuilder,但是它没有给我任何输出。两者都没有引发任何异常/错误。我的完整代码:C文件:,reutnhar.cpp,ReturnChar.h@Nawaz:Two-ways。1调用者分配,这个方法被大多数WIn32 API使用,并且非常容易在两端都得到正确的结果。2商定一个分配器。例如,丹尼斯克的回答同意函数将使用SysLaScript,调用方P/Unjk必须使用SysFielScand,因为这些是每个BSTR使用的函数。@纳瓦兹:用.NET调用方和C++ CALLY,看起来像StrugBuudRead结果=新的StrugBueDeL1000;cppfuncresult,result.Length;C++函数将是空的CPPPRANCHARAR*OUTIB BUFF,int OutuBufl长度;一个简单的例子是Win32函数GetSystemDirectory。@Nawaz:这实际上是一个inout参数,正是它的作用。调用方在调用之前设置了缓冲区,因此函数有内存可供使用。请详细说明函数的原型,并使用char变量而不是固定文本saasa?这里有几个示例,这看起来比我在这里给你的描述要好得多。你能详细描述一下函数的原型吗
使用char变量而不是固定文本saasa?刚刚在这里找到了几个示例,看起来比我在这里给出的描述要好得多。
[MarshalAs(UnmanagedType.BStr)]