[英]SQLCLR assembly registration failed (Type load failed)
I'm trying to register SQLCLR assembly in SqlServer我正在尝试在 SqlServer 中注册 SQLCLR 程序集
CREATE ASSEMBLY [DatabaseCLR]
FROM 'T:\DatabaseCLR.dll'
WITH PERMISSION_SET = SAFE
GO
but during registration I get error message但在注册期间我收到错误消息
Msg 6218, Level 16, State 2, Line 1 CREATE ASSEMBLY for assembly 'DatabaseCLR' failed because assembly 'DatabaseCLR' failed verification.消息 6218,级别 16,状态 2,第 1 行为程序集“DatabaseCLR”创建程序集失败,因为程序集“DatabaseCLR”验证失败。 Check if the referenced assemblies are up-to-date and trusted (for external_access or unsafe) to execute in the database.检查引用的程序集是否是最新的并且受信任(对于 external_access 或不安全)以在数据库中执行。 CLR Verifier error messages if any will follow this message CLR 验证器错误消息(如果有)将跟随此消息
[ : DatabaseCLR.BinaryUtils::HasSetBits][mdToken=0x6000039] Type load failed. [ : DatabaseCLR.BinaryUtils::HasSetBits][mdToken=0x6000039] 类型加载失败。
[token 0x02000008] Type load failed. [令牌 0x02000008] 类型加载失败。
which is similar to one described in this question.这类似于这个问题中描述的一个。 However the situation is a bit different.然而,情况有点不同。 In my assembly I do not use User-Defined Types.在我的程序集中,我不使用用户定义的类型。
If I use PERMISSION_SET = UNSAFE
the assembly registers successfully.如果我使用PERMISSION_SET = UNSAFE
程序集注册成功。 It doesn't seem that I use unsafe code though ("Allow unsafe code" checkbox is not checked in project properties) (or do I?).虽然我似乎没有使用不安全代码(项目属性中未选中“允许不安全代码”复选框)(或者我这样做?)。
The assembly code (simplified) is:汇编代码(简化)是:
using System;
using System.Data.SqlTypes;
using System.Runtime.InteropServices;
using Microsoft.SqlServer.Server;
namespace DatabaseCLR
{
public class BinaryUtils
{
[SqlFunction(Name = "BinaryHasSetBits", IsDeterministic = true, IsPrecise = true)]
public static SqlBoolean HasSetBits(SqlBytes data)
{
if (data.IsNull)
return SqlBoolean.Null;
if (data.Storage != StorageState.Buffer)
throw new NotSupportedException(string.Format("Storage type {0} is not supported.", data.Storage));
long
len = data.Length,
ulen = len / sizeof(ulong),
tail = len % sizeof(ulong);
ByteToUlongConverter conv = new ByteToUlongConverter(data.Buffer);
for (long i = 0; i < ulen; i++)
if (conv.ulongs[i] != 0)
return SqlBoolean.True;
for (long i = len - tail; i < len; i++)
if (data.Buffer[i] != 0)
return SqlBoolean.True;
return SqlBoolean.False;
}
}
[StructLayout(LayoutKind.Explicit)]
internal struct ByteToUlongConverter
{
[FieldOffset(0)]
public byte[] bytes;
[FieldOffset(0)]
public ulong[] ulongs;
public ByteToUlongConverter(byte[] bytes)
{
this.ulongs = null;
this.bytes = bytes;
}
}
}
The assembly provides functions for bitwise operations on binary types.该程序集提供了对二进制类型进行按位运算的函数。 I'm using struct
with [StructLayout(LayoutKind.Explicit)]
attribute for casting byte[]
array to ulong[]
array (to speed up processing).我正在使用带有[StructLayout(LayoutKind.Explicit)]
属性的struct
来将byte[]
数组转换为ulong[]
数组(以加快处理速度)。 I guess that use of StructLayout
causes error as in the related question.我猜StructLayout
使用会导致相关问题中的错误。 However it is not on UDT, and I do not see how I can fix it in this case.但是它不在 UDT 上,我不知道在这种情况下如何修复它。
Are there any chances to register assembly with PERMISSION_SET = SAFE
?是否有机会使用PERMISSION_SET = SAFE
注册程序集?
I do register my sample function as我确实将我的示例函数注册为
CREATE FUNCTION dbo.BinaryHasSetBits
(
@data varbinary(8000)
)
RETURNS BIT
AS EXTERNAL NAME [DatabaseCLR].[DatabaseCLR.BinaryUtils].[HasSetBits]
GO
I'm using x64 editions of我正在使用 x64 版本的
The error is due to use of LayoutKind.Explicit
.该错误是由于使用了LayoutKind.Explicit
。
Changing it to LayoutKind.Sequential
将其更改为LayoutKind.Sequential
[StructLayout(LayoutKind.Sequential)]
internal struct ByteToUlongConverter
{
...
}
makes possible registering assembly with PERMISSION_SET = SAFE
.可以使用PERMISSION_SET = SAFE
注册程序集。
But using LayoutKind.Sequential
instead of LayoutKind.Explicit
breaks semantics in this case.但是在这种情况下使用LayoutKind.Sequential
而不是LayoutKind.Explicit
会破坏语义。
So, PERMISSION_SET = SAFE
or LayoutKind.Explicit
, not both.因此, PERMISSION_SET = SAFE
或LayoutKind.Explicit
,而不是两者。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.