SQL 服务器:"CREATE ASSEMBLY for assembly 'Test' failed because assembly 'Test' is malformed or not a pure .NET assembly."

SQL Server: "CREATE ASSEMBLY for assembly 'Test' failed because assembly 'Test' is malformed or not a pure .NET assembly."

当我尝试将混合模式 C++/CLI 程序集加载到 SQL Server 2012 时出现此错误:

CREATE ASSEMBLY [Test]
AUTHORIZATION [dbo]
from 'H:\test.dll'
WITH PERMISSION_SET = SAFE

Msg 6544, Level 16, State 1, Line 1 CREATE ASSEMBLY for assembly 'Test' failed because assembly 'Test.dll' is malformed or not a pure .NET assembly. Unverifiable PE Header/native stub.

无法将混合模式 C++/CLI 程序集加载到 SQL 服务器。

您只能加载“纯”C++/CLI 程序集:

不过,可能有办法解决这个问题。在 C# 文件中使用 P/Invoke。这相当于编写混合模式 C++/CLI 程序集包装器,因为当 CLR 代码调用程序集中的 native 代码时,它会执行隐式 P/Invoke(请告诉我这是否适用于你)。

为什么 SQL 服务器阻止加载混合模式程序集?

这是我的理论:

If we go back to 2005, things were different. When they released the first version of SQL Server to support the CLR, mixed mode assemblies would sometimes deadlock on a load. See Microsoft - Mixed DLL Loading Problem. Even after they fixed this issue, there was still arguments centered around security and stability which tipped the scales against allowing loading of mixed mode C++/CLI assemblies into the core of SQL server.

如果原微软设计团队的任何人都可以填补空白,我会很好奇!

SQLCLR 程序集中不允许使用混合模式程序集;只允许使用纯 MSIL 程序集。 备注 部分的 CREATE ASSEMBLY 的 MSDN 文档中暗示了这一点:

Assembly Validation
SQL Server performs checks on the assembly binaries uploaded by the CREATE ASSEMBLY statement to guarantee the following:

  • The assembly binary is well formed with valid metadata and code segments, and the code segments have valid Microsoft Intermediate language (MSIL) instructions.

有关详细信息,请参阅以下答案(也在 Stack Overflow 上):

尤其是 Microsoft 知识库文章 Support policy for untested .NET Framework assemblies in the SQL Server CLR-hosted environment 中的 link,其中说明了此限制。

只允许托管代码的一个可能原因是允许非托管代码可能会阻止 SQL 服务器对 SAFE 和 [=11] 实施某些限制(即主机保护属性等) =] 级别,以及防止验证。

虽然将 Assembly 设置为 UNSAFE 解除了大部分限制,但仍然强制执行此限制:

Runtime Checks

At runtime, the code assembly is checked for the following conditions. If any of these conditions are found, the managed code will not be allowed to run and an exception will be thrown.

UNSAFE

Loading an assembly—either explicitly by calling the System.Reflection.Assembly.Load() method from a byte array, or implicitly through the use of Reflection.Emit namespace—is not permitted.

以上引用摘自以下 MSDN 页面:CLR Integration Programming Model Restrictions.

更多信息位于:CLR Hosted Environment