System.EntryPointNotFoundException即使在c#代码中指定entrypoint(函数名)后也是如此

System.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

浏览了大量文章和堆栈溢出链接,但未能找到解决方案,或者可能犯了一些愚蠢的错误。因此,如果有人能帮我解决问题,请在这里发布我的代码。非常感谢。提前谢谢

extern.cpp

#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");  
} 
我尝试了一些设置,但没有成功:

  • 已从cpp项目属性启用CLR支持。 错误:严重性代码说明项目文件行抑制状态 错误D8016'/clr'和'/EHs'命令行选项不兼容MemoryTestApp[项目路径]

  • 将CPP项目属性中的调用约定设置为_cdecl(/Gd)。我还尝试使用u stdcall在文件中指定

    [DllImport(DllFilePath,EntryPoint=“FillAndReturnString”,CallingConvention=CallingConvention.StdCall)] 公共静态外部无效填充和返回字符串(参考IntPtr ptr)

  • 已使用Dependency Walker检查cpp dll,但它引发错误:未找到至少一个必需的隐式或转发依赖项


  • 这种方法从根本上说是有缺陷的,因为您的非托管函数使用
    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);
        }
    }