System.EntryPointNotFoundException即使在c#代码中指定entrypoint(函数名)后也是如此
浏览了大量文章和堆栈溢出链接,但未能找到解决方案,或者可能犯了一些愚蠢的错误。因此,如果有人能帮我解决问题,请在这里发布我的代码。非常感谢。提前谢谢 extern.cppSystem.EntryPointNotFoundException即使在c#代码中指定entrypoint(函数名)后也是如此,c#,exception,C#,Exception,浏览了大量文章和堆栈溢出链接,但未能找到解决方案,或者可能犯了一些愚蠢的错误。因此,如果有人能帮我解决问题,请在这里发布我的代码。非常感谢。提前谢谢 extern.cpp #define EXPORT extern "C" __declspec( dllexport ) __cdecl FillAndReturnString(char **someString); #include <string.h> #include <stdlib.h> static void
#define EXPORT extern "C" __declspec( dllexport ) __cdecl FillAndReturnString(char **someString);
#include <string.h>
#include <stdlib.h>
static void _stdcall FillAndReturnString(char **someString)
{
*someString = (char*)malloc(sizeof(200));
strcpy_s(*someString, 200, "This is a sample Test");
}
我尝试了一些设置,但没有成功:
这种方法从根本上说是有缺陷的,因为您的非托管函数使用
malloc
分配一个托管代码无法释放的字符串。一个实FillAndReturnString
函数需要一个(分配的)缓冲区和一个大小。这是一个玩具示例,还是您的意思是与实际的非托管代码进行互操作?基本上,我需要帮助来解决异常。我尝试了两种方法,但都没有成功。关于内存分配部分,我同意使用malloc而不是指定缓冲区大小参数来释放它,或者使用CoTaskMemAlloc可能有助于使用封送来释放它,但我稍后将对此进行检查。您在发布的代码中是否有任何错误导致了此异常或我遗漏的任何内容?最突出的问题是什么都不做#定义导出。要导出函数,请将原型声明为extern“C”\uu declspec(dllexport)void\uu stdcall FillAndReturnString(…)
。您可以使用dumpbin/exports
验证DLL从VS命令提示符实际导出的内容;正确的入口点看起来像_FunctionName@X
,用X表示参数的总大小(以字节为单位)。不过,这只是事情的开始;您将需要了解如何进行正确的字符串封送处理<代码>StringBuilder
比手动旋转指针方便得多。要清楚,在上面,我不是指…
字面意思,我只是太懒了,没有写出参数。在大多数语言中,这不是问题,但在C和C++中,这是一个合法声明,它是一个VARARGS函数。但那不是你想要的谢谢Jeroen。在进行建议的更改后,代码工作正常。我必须使用interop的原因是根据项目要求通过c#释放内存。
using System;
using System.Runtime.InteropServices;
namespace CallingCpp
{
class Program
{
static void Main(string[] args)
{
IntPtr ptr = IntPtr.Zero;
NativeTest.FillAndReturnString(ref ptr);
String s = Marshal.PtrToStringAnsi(ptr);
Console.WriteLine(s);
Console.ReadKey();
}
}
public static class NativeTest
{
private const string DllFilePath = @"C:\Test\MemoryTest\MemoryTestApp.dll";
[DllImport(DllFilePath, EntryPoint = "FillAndReturnString")]
public static extern void FillAndReturnString(ref IntPtr ptr);
}
}