gpt4 book ai didi

C# 程序在 C DLL 中找不到函数

转载 作者:太空宇宙 更新时间:2023-11-04 01:56:47 25 4
gpt4 key购买 nike

我在使用 C# 程序调用 C DLL 中的函数时遇到问题。我正在使用 VS 2015。

对 XBaseResolveAll 的第一次调用有效,但对 XBaseSeek 的调用导致弹出窗口说:

An unhandled exception of type 'System.EntryPointNotFoundException' occurred in Call_C.exe

Additional information: Unable to find an entry point named 'XBaseSeek' in DLL 'W:\C_sharp\Call_C\Debug\C_dll.dll'.

请注意,dll 的转储文件显示所有函数都已按预期导出。请参阅下面的输出。

我试过搜索但没有发现讨论过这个问题。所以我一定是在做一些愚蠢的事情,但我只是没有看到它。我创建了一个小样本来说明问题。

有人可以帮忙吗?

下面是示例文件:

----------
Program.cs
----------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using XBaseNamespace.SecondNamespace;


namespace Call_C
{
class Program
{

static void Main()
{
XBaseFunctions.XBaseResolveAll();
XBaseFunctions.XBaseSeek(UIntPtr.Zero, 0, 0);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
}

-----------------
XBaseNamespace.cs
-----------------
// XBase functions
using System;
using System.Runtime.InteropServices;

namespace XBaseNamespace.SecondNamespace
{
class XBaseFunctions
{
[DllImport("W:\\C_sharp\\Call_C\\Debug\\C_dll.dll", CharSet = CharSet.Ansi)]
public static extern int XBaseResolveAll();

[DllImport("W:\\C_sharp\\Call_C\\Debug\\C_dll.dll", CharSet = CharSet.Ansi)]
public static extern int XBaseSeek(UIntPtr myhandle, long offset, int origin);
}

}

-------
c_dll.c
-------
// C DLL experiment

#include <stdio.h>

#define DSI_DLL __declspec(dllexport)
#define CALL_TYPE __stdcall

DSI_DLL int CALL_TYPE XBaseResolveAll()
{
return 0;
}


DSI_DLL int CALL_TYPE XBaseSeek(unsigned int *handle, long offset, int origin)
{
return 0;
}

---------------
Output of build
---------------
1>------ Rebuild All started: Project: C_dll, Configuration: Debug Win32 ------
1> c_dll.c
1> Creating library W:\C_sharp\Call_C\Debug\C_dll.lib and object W:\C_sharp\Call_C\Debug\C_dll.exp
1> C_dll.vcxproj -> W:\C_sharp\Call_C\Debug\C_dll.dll
2>------ Rebuild All started: Project: Call_C, Configuration: Debug Any CPU ------
2> Call_C -> W:\C_sharp\Call_C\bin\Debug\Call_C.exe
========== Rebuild All: 2 succeeded, 0 failed, 0 skipped ==========

-----------------------
output from dumbbin.exe
-----------------------

C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE>"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\dumpbin.exe" /exports "W:\C_sharp\Call_C
\Debug\C_dll.dll"
Microsoft (R) COFF/PE Dumper Version 11.00.60610.1
Copyright (C) Microsoft Corporation. All rights reserved.


Dump of file W:\C_sharp\Call_C\Debug\C_dll.dll

File Type: DLL

Section contains the following exports for C_dll.dll

00000000 characteristics
562D7696 time date stamp Sun Oct 25 20:40:54 2015
0.00 version
1 ordinal base
2 number of functions
2 number of names

ordinal hint RVA name

1 0 00011028 _XBaseResolveAll@0 = @ILT+35(_XBaseResolveAll@0)
2 1 00011082 _XBaseSeek@12 = @ILT+125(_XBaseSeek@12)

Summary

1000 .00cfg
1000 .data
1000 .idata
2000 .rdata
1000 .reloc
1000 .rsrc
5000 .text
10000 .textbss

C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE>

最佳答案

根据您的 dumpbin 输出,DLL 导出表中的函数名称已被“修饰”为包含有关参数数量的信息。您需要禁用名称修饰,或在 C# 代码中的 DllImport 中使用修饰的名称。就个人而言,我会禁用名称装饰。您可以通过在 DLL 项目中创建模块定义文件 (.def) 并列出导出的函数名称来禁用导出函数的名称修饰。示例:

LIBRARY C_dll
EXPORTS
XBaseResolveAll
XBaseSeek

此外,在您的 C# 代码中包括调用约定作为 DllImport 的一部分:

[DllImport("W:\\C_sharp\\Call_C\\Debug\\C_dll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]

编辑(10/26/2015):

仔细检查 .def 文件中的语法,并确保 .def 文件已添加到解决方案中并在链接器设置下列为模块定义文件。下面是一个简单的例子来证明这确实有效:

  1. 我使用单个源文件 (Example.c) 创建了一个新的解决方案 (Win32 DLL):
#include <Windows.h>__declspec(dllexport) int __stdcall ExampleFunction(int param1, int param2){    return 0;}
  1. 我构建了解决方案,然后在生成的 ExampleDll.dll 上运行 dumpbin。结果如下所示(显示经过修饰的名称):
Dump of file ExampleDll.dllFile Type: DLL  Section contains the following exports for ExampleDll.dll    00000000 characteristics    562E5A83 time date stamp Mon Oct 26 12:53:23 2015        0.00 version           1 ordinal base           1 number of functions           1 number of names    ordinal hint RVA      name          1    0 0001100F _ExampleFunction@8 = @ILT+10(_ExampleFunction@8)
  1. 我将以下 .def 文件 (Example.def) 添加到我的解决方案中,然后仔细检查该文件是否在项目设置(链接器、输入、模块定义文件)中列为模块定义文件 ).
LIBRARY ExampleDllEXPORTS    ExampleFunction
  1. 最后,我在新的 ExampleDll.Dll 上重建并重新运行 dumpbin(显示名称修饰已被删除):
Dump of file ExampleDll.dllFile Type: DLL  Section contains the following exports for ExampleDll.dll    00000000 characteristics    562E5CBF time date stamp Mon Oct 26 13:02:55 2015        0.00 version           1 ordinal base           1 number of functions           1 number of names    ordinal hint RVA      name          1    0 0001100F ExampleFunction = @ILT+10(_ExampleFunction@8)

关于将 CallingConvention 添加到 C# 代码中的 [DllImport] 的问题,请仔细检查您的语法。如果没有明显错误,请将您的代码与错误消息一起发布。

关于C# 程序在 C DLL 中找不到函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33336892/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com