为什么调用C#DLL时不需要提供字符串缓冲区? 我知道当C++调用方使用另一个C++ DLL时,调用方必须分配一个具有一定MAX大小的字符串,并将该指针和最大大小传递给C++ CALLY/DLL。 所以C++调用方会做如下的事情: MyCPPDllFunction(char *out, int maxOutSize); 现在我知道,当C++调用方使用C语言的DLL时,它可以是这样的: char *output = MyCSharpDllFunction(); P>我不明白C语言被调用的人如何分配内存,C++中的CALLY不能这样做? < P>我猜原因如下: 从C++调用C.API API时,调用CLR Virtual Engual机所管理的代码,因此内存分配由虚拟机本身自动管理,免除手动缓冲区分配的麻烦。 < P>从C++调用Cy.API时,调用CLR Virtual Engual机所管理的代码,因此内存分配由虚拟机本身自动管理,免除手动缓冲区分配的麻烦。它仅由函数的调用签名定义。因此,我可以用C++编写以下DLL源代码: #include <windows.h> BOOL WINAPI DllMain( _In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved ) { return TRUE; } __declspec(dllexport) char *function1() { char *foo = new char[100]; // do stuff to fill in foo return foo; } __declspec(dllexport) void function2(char *out, int maxOutSize) { // do stuff to fill in out } #包括 布尔WINAPI DllMain( _在HINSTANCE hinstDLL中, _在德沃德·弗雷森, _已保留无效的LPV ) { 返回TRUE; } __declspec(dllexport)字符*function1() { char*foo=新字符[100]; //做些事情来填foo 返回foo; } __declspec(dllexport)void函数2(char*out,int-maxOutSize) { //填表 } 这是完全合法的,并定义了C++签名入口点,这些签名与OP问题中列出的函数完全匹配。 注意,使用C++ >代码> NeX[]/Cuff>分配内存为函数>(/>代码>,因此有必要在某个时间点使用删除[]/COD> 在类似的情况下,如果内存被CLR在C语言中分配,那么你需要把它传递给C语言的DLL,以便正确地释放,或者在C++中找到一个安全的方法来破坏它,假设这样的操作是可能的。 我将在这里诚实100%,如果C++运行时和C ^ CLR与内存分配一起玩得很好,我就完全没有线索了。因此,唯一的选择可能是将其传递回C#进行解除分配

为什么调用C#DLL时不需要提供字符串缓冲区? 我知道当C++调用方使用另一个C++ DLL时,调用方必须分配一个具有一定MAX大小的字符串,并将该指针和最大大小传递给C++ CALLY/DLL。 所以C++调用方会做如下的事情: MyCPPDllFunction(char *out, int maxOutSize); 现在我知道,当C++调用方使用C语言的DLL时,它可以是这样的: char *output = MyCSharpDllFunction(); P>我不明白C语言被调用的人如何分配内存,C++中的CALLY不能这样做? < P>我猜原因如下: 从C++调用C.API API时,调用CLR Virtual Engual机所管理的代码,因此内存分配由虚拟机本身自动管理,免除手动缓冲区分配的麻烦。 < P>从C++调用Cy.API时,调用CLR Virtual Engual机所管理的代码,因此内存分配由虚拟机本身自动管理,免除手动缓冲区分配的麻烦。它仅由函数的调用签名定义。因此,我可以用C++编写以下DLL源代码: #include <windows.h> BOOL WINAPI DllMain( _In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved ) { return TRUE; } __declspec(dllexport) char *function1() { char *foo = new char[100]; // do stuff to fill in foo return foo; } __declspec(dllexport) void function2(char *out, int maxOutSize) { // do stuff to fill in out } #包括 布尔WINAPI DllMain( _在HINSTANCE hinstDLL中, _在德沃德·弗雷森, _已保留无效的LPV ) { 返回TRUE; } __declspec(dllexport)字符*function1() { char*foo=新字符[100]; //做些事情来填foo 返回foo; } __declspec(dllexport)void函数2(char*out,int-maxOutSize) { //填表 } 这是完全合法的,并定义了C++签名入口点,这些签名与OP问题中列出的函数完全匹配。 注意,使用C++ >代码> NeX[]/Cuff>分配内存为函数>(/>代码>,因此有必要在某个时间点使用删除[]/COD> 在类似的情况下,如果内存被CLR在C语言中分配,那么你需要把它传递给C语言的DLL,以便正确地释放,或者在C++中找到一个安全的方法来破坏它,假设这样的操作是可能的。 我将在这里诚实100%,如果C++运行时和C ^ CLR与内存分配一起玩得很好,我就完全没有线索了。因此,唯一的选择可能是将其传递回C#进行解除分配,c#,c++,dll,com,C#,C++,Dll,Com,--编辑-- 我也将把这个问题联系起来以供进一步参考,因为它涉及到对同一问题的不同观点,尤其是公认的答案中包含了一些非常有用的信息 返回值的方式与使用的语言无关。它仅由函数的调用签名定义。因此,我可以用C++编写以下DLL源代码: #include <windows.h> BOOL WINAPI DllMain( _In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved )

--编辑--

我也将把这个问题联系起来以供进一步参考,因为它涉及到对同一问题的不同观点,尤其是公认的答案中包含了一些非常有用的信息


返回值的方式与使用的语言无关。它仅由函数的调用签名定义。因此,我可以用C++编写以下DLL源代码:

#include <windows.h>

BOOL WINAPI DllMain(
  _In_ HINSTANCE hinstDLL,
  _In_ DWORD     fdwReason,
  _In_ LPVOID    lpvReserved
)
{
    return TRUE;
}

__declspec(dllexport) char *function1()
{
    char *foo = new char[100];
    // do stuff to fill in foo
    return foo;
}

__declspec(dllexport) void function2(char *out, int maxOutSize)
{
    // do stuff to fill in out
}
#包括
布尔WINAPI DllMain(
_在HINSTANCE hinstDLL中,
_在德沃德·弗雷森,
_已保留无效的LPV
)
{
返回TRUE;
}
__declspec(dllexport)字符*function1()
{
char*foo=新字符[100];
//做些事情来填foo
返回foo;
}
__declspec(dllexport)void函数2(char*out,int-maxOutSize)
{
//填表
}

这是完全合法的,并定义了C++签名入口点,这些签名与OP问题中列出的函数完全匹配。

注意,使用C++ >代码> NeX[]/Cuff>分配内存为<代码>函数>(/>代码>,因此有必要在某个时间点使用<代码>删除[]/COD>

在类似的情况下,如果内存被CLR在C语言中分配,那么你需要把它传递给C语言的DLL,以便正确地释放,或者在C++中找到一个安全的方法来破坏它,假设这样的操作是可能的。 我将在这里诚实100%,如果C++运行时和C ^ CLR与内存分配一起玩得很好,我就完全没有线索了。因此,唯一的选择可能是将其传递回C#进行解除分配

--编辑--

我也将把这个问题联系起来以供进一步参考,因为它涉及到对同一问题的不同观点,尤其是公认的答案中包含了一些非常有用的信息

< P> > P>我不理解C++的CALLY是如何分配内存的,C++的CalLee不能在这里使用< < /P> 您正在寻找错误的问题。问题不在于“C#如何分配内存”。任何人都可以分配内存。。。在很多方面:-)问题总是如何释放内存?因为释放内存与分配内存一样重要(不释放内存会导致内存泄漏,这会使程序内存占用膨胀,而使用错误的分配器释放内存至少不会释放内存(请参见上一点),最坏情况下会使程序崩溃)

现在,操作系统(例如Windows)为您提供了一些任何人都可以使用的分配器(
CoTaskMemAlloc
),但问题是,通常在C/C++中,您将使用
malloc
/
new
。问题在于:这些分配器在两个DLL之间可能“不同”(不同):两个在C/C++中编译的DLL(但是,例如Visual C++的不同版本,或者在调试和发布模式下,或者使用运行时作为DLL,而另一个直接连接运行时,或者用不同的C编译器编译)将具有不同的<代码> MalOC (并且在C++中有不同的代码>新的< /代码>)。具有独立的
malloc
/
新建
它们将具有独立的
空闲
/
删除
,因此一个dll的
空闲
不能释放另一个dll的内存

现在…使用此签名:

void MyCPPDllFunction(char *out, int maxOutSize);
char *MyCPPDllFunction();
调用者必须分配内存…以便调用者知道如何释放内存…无内存泄漏:-)

签名如下:

void MyCPPDllFunction(char *out, int maxOutSize);
char *MyCPPDllFunction();
被调用者必须分配内存…现在调用者如何释放内存?被调用者可以导出另一个方法:

void FreeMemoryAllocatedByMe(void *ptr)
{
    free(ptr);
}
t