我非常怀疑我的问题是由于某些安全问题造成的,但这里有完整的描述,以防我误会。
我有一个最初用C(不是C ++)编写的DLL。我正在使用DllImport来调用此库中的方法。声明看起来像这样:
[DllImport(@"MyAntiquatedLibrary.dll")
[SecurityPermission(SecurityAction.Assert, Unrestricted = true)]
internal static extern void GetConnectionString(string port, string server, string instance, [Out] StringBuilder output);
头文件中的C声明如下所示:
void GetConnectionString(const char far *Portname, const char far *ServerName const char far *InstanceName, char far *retConnectionName);
所以我在visual studio的WebApplication项目中创建了一个示例页面,其代码隐藏如下:
protected void Page_Load(object sender, EventArgs e)
{
try
{
var connectionString = new StringBuilder();
GetConnectionString(null, "myHost", "myInstance", connectionString);
MyLabel.Text = connectionString.ToString();
}
catch(Exception ex)
{
MyLabel.Text = string.Format("Something went wrong: {0}", ex.Message);
}
}
当我调试程序并跳过GetConnectionString()方法调用时,我得到一个:
AccessViolationException was unhandled.
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
我在WebApplication项目中从Web服务或网页对interop DLL进行的任何调用都会出现同样的问题。在我测试时编写的ConsoleApplication中,相同的调用序列工作正常。
从WindowsConsole应用程序调用时,相同的代码工作正常。该示例从实际使用中略微简化,但结果是相同的。在真正的解决方案中,我有一个项目,负责管理与C-API的交互,这就是我的web服务所调用的,但我已经运行了上面的示例并获得了我解释的行为。
答案 0 :(得分:1)
如果您的IIS服务器在64位操作系统中运行,您应该明确地使用目标CPU = X86构建项目,否则它将被视为AnyCPU,jit可能会为其生成64位本机代码。执行此操作后,您可以在IIS中启用32位应用程序,您的项目应该可以工作。 要检查的是,您的dll实际上是由您的asp.net应用程序找到的。
答案 1 :(得分:1)
最后问题是我没有正确初始化C-API。有一个函数调用初始化整个API,当我在我的UnitTests中这样做时,我忘了在webservice中这样做。
感谢大家的帮助,我觉得我已经学到了很多关于ASP.NET安全模型和.NET信任实现的知识。