我有本机非托管dll是静态的,每次当我需要库做一些工作时如果我想并行运行它必须加载。在.NET中,我会使用AppDomain并在需要时加载此dll,但在.NET Core AppDomains中已经消失(暂时)。我查看了AssemblyLoadContext,但没有适当的LoadUnmanagedDll文档。这可以在netstandard1.6中完成吗?
修改 目前使用PInvoke调用代码并且工作正常。问题是因为这个unmanged dll的性质,当我尝试并行调用它时抛出AccessViolationException,因为两个或更多任务想要访问相同的内存。
如果我可以在某些上下文中每次加载dll然后调用PInvoke,那么这个问题就会消失。
答案 0 :(得分:3)
一种方法:
headers = ['APPL', 'Std_1', 'Std_2', 'Std_3', 'Mean']
values = [['ACCMGR', 106.8754, 130.1600, 107.1861, 114.750510],
['ACCOUNTS', 121.7034, 113.4927, 114.5482, 116.581458],
['AUTH', 116.8585, 112.4487, 115.2700, 114.859050]]
df = pd.DataFrame(values, columns=headers)
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 5 columns):
APPL 3 non-null object
Std_1 3 non-null float64
Std_2 3 non-null float64
Std_3 3 non-null float64
Mean 3 non-null float64
dtypes: float64(4), object(1)
memory usage: 200.0+ bytes
def make_count(comp_cols, mean_col):
count_d = {'greater': 0, 'less': 0}
for col in comp_cols:
if col > mean_col:
count_d['greater'] += 1
elif col < mean_col:
count_d['less'] += 1
return count_d['greater'], count_d['less'], (count_d['greater'] + count_d['less'])
def apply_make_count(df):
a, b, c = df.apply(lambda row: make_count([row['Std_1'], row['Std_2'], row['Std_3']], row['Mean']), axis=1)
df['greater'], df['less'], df['count'] = list(zip(a, b, c))
apply_make_count(df)
df =
APPL Std_1 Std_2 Std_3 Mean greater less count
0 ACCMGR 106.8754 130.1600 107.1861 114.750510 1 2 3
1 ACCOUNTS 121.7034 113.4927 114.5482 116.581458 1 2 3
2 AUTH 116.8585 112.4487 115.2700 114.859050 2 1 3
派生课程System.Runtime.Loader.AssemblyLoadContext
并调用Load(AssemblyName assemblyName)
或将null返回到后备状态LoadFromAssemblyPath()
并调用IntPtr LoadUnmanagedDll(string unmanagedDllName)
以加载您的本机dll LoadUnmanagedDllFromPath()
间接访问您的pinvoke方法并加载本机/非托管库第4步是您需要根据现有代码的结构进行调整的部分。就我而言,我创建了3个程序集:
在调用代码中:
interface
当var assem = assemblyLoadContext.LoadFromAssemblyName(new
System.Reflection.AssemblyName(pinvokeAssemblyName));
var type = assem.GetType(nameOfTypeThatCallsPinvoke);
return (ISharedInterface)Activator.CreateInstance(type);
实例尝试使用pinvoke方法时,将调用您在加载上下文上的nameOfTypeThatCallsPinvoke
覆盖。
需要共享接口,因此在编译时就知道类型。如果调用代码直接引用了pinvoke库,则其类型将不同于通过加载上下文获得的类型。
参考文献: