C# 使用C++;C“windows应用程序:获取错误”中的DLL;“未找到入口点”; 我在C语言中使用C++库,一般也可以使用C++编程。我有一个从C++代码构建的DLL,我相信它是一个“托管”代码,因为DLL的名称是“TestMalkest.DLL”。我不能100%确定dll/C++代码是托管的还是非托管的
我想在我的C# 使用C++;C“windows应用程序:获取错误”中的DLL;“未找到入口点”; 我在C语言中使用C++库,一般也可以使用C++编程。我有一个从C++代码构建的DLL,我相信它是一个“托管”代码,因为DLL的名称是“TestMalkest.DLL”。我不能100%确定dll/C++代码是托管的还是非托管的,c#,c++,dllimport,dependency-walker,C#,C++,Dllimport,Dependency Walker,我想在我的C#windows窗体应用程序中使用此DLL的类和方法。此DLL中有多个类。当我在对象浏览器中检查这些类中的类和方法时,它们都有公共标识符 到目前为止,我已经将这个DLL添加到我对C#应用程序代码的引用中。在我的问题中,我将讨论三个类:Product,ReqStatus,ProductData。我可以为这个DLL的不同类创建一个对象,如下所示 Product testCall = new ProductClass(); 这个DLL中还有一个类叫做“代码>产品数据< /代码>,我可以得
C#windows窗体应用程序中使用此DLL的类和方法。此DLL中有多个类。当我在对象浏览器
中检查这些类中的类和方法时,它们都有公共
标识符
到目前为止,我已经将这个DLL添加到我对C#应用程序代码的引用中。在我的问题中,我将讨论三个类:Product
,ReqStatus
,ProductData
。我可以为这个DLL的不同类创建一个对象,如下所示
Product testCall = new ProductClass();
这个DLL中还有一个类叫做“代码>产品数据< /代码>,我可以得到这个类的C++代码,如下所示。在这种情况下,产品数据>代码>在C代码中显示为对象浏览器< /C> >,因为它实际上是C++代码中的一个结构。我不确定这对回答我的问题(最后)是否重要
以下是一个C++代码,定义了代码>产品数据>代码>结构>代码>产品数据.h < /C>文件>p>
#ifdef WIN32_MANAGED
public ref struct ProductData
#else
struct ProductData
#endif
{
UINT32 ProductId; //!< Product ID
UINT32 PRoductRev; //!< Build Revision
};
现在,我想调用两种方法,但这两种方法都有问题:
< P>方法1:代码< >代码>产品>代码>类,它接受代码“<产品数据> /COD> >类型的对象作为参数,并返回C++中的EnUM类型<代码> ReqStase<代码>。下面是gerProductData
方法的声明(如对象浏览器中所示):
同一方法的C++删除是:(实际方法太长,因此只给出声明):此方法在代码> PRODCUT.CPP < /Cord>文件< /P>内。
ReqStatus Product::getProductData(ProductData PLATFORM_PTR data)
ReqStatus Product::getConnected(const char *someChar, ProductData PLATFORM_PTR data)
平台PTR在PLATFORM.h
#ifdef WIN32_MANAGED
#define PLATFORM_PTR ^
#else
#define PLATFORM_PTR *
#endif
< P>方法2:是代码< >代码>产品< /Cuff>类,它接受字符数组(我不确定这一点)和对象“代码>产品数据< /代码>类型作为参数,并返回C++中的EnUM类型<代码> ReqStase<代码>。下面是getConnected
方法的声明(如对象浏览器中所示):
同一方法的C++删除是:(实际方法太长,因此只给出声明):此方法在代码> PRODCUT.CPP < /Cord>文件< /P>内。
ReqStatus Product::getProductData(ProductData PLATFORM_PTR data)
ReqStatus Product::getConnected(const char *someChar, ProductData PLATFORM_PTR data)
C++代码调用方法如下:
private : Product^ _testProduct;
testProduct = gcnew Product();
ProductData ^ data = gcnew ProductData();
int portNum = Decimal::ToInt16(7);
char portName[32];
_snprintf(&portName[0], sizeof(portName),"COM%d", portNum);
ReqStatus status = _testProduct->getConnected(&portName[0], data); //Calling getConnected
在getConnected
方法中有对getProductData
方法的内部调用
ReqStatus status = getProductData(data); //data is the same which was passed to the getConnected method
我的C#代码如下,并且在两个方法调用中都出现了错误:我在下面的代码段中的同一行中放置了错误。两种方法都是独立的。它只是从C++代码中的<代码> GETCONTIONE>代码>中调用了<代码> GETOPTIOTATEATION<代码>。我想看看我是否可以分别给两个人打电话
ProductData pData = new ProductData(); // OK
Product _testProduct = new Product(); // OK
ReqStatus status1 = _testProduct.getConnected("COM5", pData ); //Error 1: The best overloaded method getConnected has some invalid arguments
ReqStatus status2 = (ReqStatus)_testProduct.getProductData(pData ); // Error 2: Method is inaccessible due to its protection level
对于错误1,我尝试了StackOverflow和其他论坛上各种文章的解决方案,但未能解决。仅供参考,我尝试如下更改“SomePortCOM”,但不起作用
更新:这段代码现在运行正常,我没有看到错误1(无效参数)。现在,我只需要去掉错误2(保护级别错误)。请提供任何建议。谢谢。
String str = "COM5";
byte[] bytes = Encoding.ASCII.GetBytes(str);
unsafe
{
fixed (byte* p = bytes)
{
sbyte* sp = (sbyte*)p;
//SP is now what you want
ReqStatus status1 = _testProduct.getConnected(sp, pData );
}
}
对于错误2,我搜索了很多博客,发现可能的解决方案之一是使用DLLImport,我也尝试过,我有以下问题:
C#德林波特宣言:
[DllImport("TestManaged.dll",EntryPoint="getConnected")]
public static extern ReqStatus getConnected(String SerialPort, ref ProductData pData);
我从C#代码调用此函数,如下所示:
但是,我发现入口点未找到
错误。我试图运行dumpbin函数以获取此DLL导出的函数列表。但是,我没有看到任何功能。而只是一个随机输出,如下所示
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file C:\Rumit\TestManaged.dll
File Type: DLL
Summary
2000 .data
22000 .rdata
1000 .reloc
1000 .rsrc
13000 .text
更新:
此外,我在这个DLL中没有通过依赖项遍历器看到任何方法。
现在,我已经得到了C++的源代码。但是我对C++编码还是比较新的。如果对C++代码需要任何更改,请给出说明。>/P>
问候,,
Rumit代码周围的不安全块会使程序集无法验证安全协议,因此要小心。当我从C++调用了来自C++的方法(原生或不存在)时,我不得不使用PInvoke(平台调用)来调用它们。对于保护级别,我知道您说C++中所有的内容都是公开的,但是如果您是C++新手,您可能犯了一个快速语法错误。在C语言中,所有方法都需要一个存储说明符(public、受保护等),但是在C++中,放置一个存储标识符,后面跟着冒号,并且在该存储和下一个声明的存储之间的所有内容都将是该存储类型。也许这是您的问题?代码周围的不安全块将导致程序集无法验证安全协议,因此请小心。当我从C++调用了来自C++的方法(原生或不存在)时,我不得不使用PInvoke(平台调用)来调用它们。对于保护级别,我知道您说C++中所有的内容都是公开的,但是如果您是C++新手,您可能犯了一个快速语法错误。在C语言中,所有方法都需要一个存储说明符(public、受保护等),但是在C++中,放置一个存储标识符,后面跟着冒号,并且在该存储和下一个声明的存储之间的所有内容都将是该存储类型。也许这是你的问题
enum ReqStatus
这是你最大的障碍。声明本机枚举类型时,它在托管代码中不可用,并使使用它的任何代码都无法访问。必须使用enum class关键字声明其托管版本,如下所示:
public enum class ReqStatus {
// etc...
}
这是你最大的障碍。声明本机枚举类型时,该类型在托管代码中不可用,并使任何使用该类型的代码都不可用
enum ReqStatus
public enum class ReqStatus {
// etc...
}