gpt4 book ai didi

visual-studio - 在 F# 中调用另一个 dll 的类型提供程序

转载 作者:行者123 更新时间:2023-12-04 06:16:44 25 4
gpt4 key购买 nike

在为提供的类型构建内部表示时,我在引用中间接调用我的类型的内部表示,即另一个 dll,我可以修改其代码。

目前,当我使用类型提供程序时,告诉我它找不到这样的 dll:

“无法加载文件或程序集 xxxx 或其依赖项之一”

但是,当我使用 Process Explorer 检查 VS 时,我可以看到加载的 dll XXX...
有什么办法让引号中的代码接受来自外部 dll 的代码?

** 更新 **

我尝试了一个简化的示例,似乎可以调用这样的外部 dll 而无需做任何特殊的事情。就我而言,所有依赖的 dll XXX 都已加载,当我调试 devenv.exe 本身时,我会在进程资源管理器以及模块窗口中看到它们......

我不知道该去哪里找。这是内部异常。

** 更新 **

如果我将 xxx dll 及其依赖项复制到此路径之一中,则编译器可以正常工作。
我仍然想知道什么可以触发 devenv.exe 正确显示它们已加载但无法访问。

=== Pre-bind state information ===
LOG: User = xxx\Administrator
LOG: DisplayName = bloombergapi, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Users\Administrator\AppData\Local\Microsoft\VisualStudio\11.0\devenv.exe.config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/bloombergapi.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/bloombergapi/bloombergapi.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/PublicAssemblies/bloombergapi.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/PublicAssemblies/bloombergapi/bloombergapi.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/PrivateAssemblies/bloombergapi.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/PrivateAssemblies/bloombergapi/bloombergapi.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/CommonExtensions/Microsoft/TemplateProviders/bloombergapi.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/CommonExtensions/Microsoft/TemplateProviders/bloombergapi/bloombergapi.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/CommonExtensions/Platform/Debugger/bloombergapi.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/CommonExtensions/Platform/Debugger/bloombergapi/bloombergapi.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/PrivateAssemblies/DataCollectors/bloombergapi.DLL.

...

回答

调用一个将另一个库中的类型作为参数的函数似乎是不可能的。
联合类型有效,但不是正确的类型......
如下图所示

--库.dll
namespace Library

module SampleModule =
type LocalUnion = | LocalUnion of int

type Localtype() =
member x.value = 2

--库TP.dll
namespace LibraryTP

module Module =
open System.Reflection
open Samples.FSharp.ProvidedTypes
open FSharpx.TypeProviders.DSL
open Microsoft.FSharp.Core.CompilerServices

let f a =
Library.SampleModule.sampleFunction a a

let g (a:Library.SampleModule.LocalUnion) =
let (Library.SampleModule.LocalUnion(v)) = a
v

let ftype (a:Library.SampleModule.Localtype) =
a.value

let createTP ns =
erasedType<obj> (Assembly.GetExecutingAssembly()) ns "Outside"
|> staticParameter "file"
(fun typeName (parameterValues:string) ->
erasedType<obj> (Assembly.GetExecutingAssembly()) ns typeName
|+!> ( provideProperty
"test" //OK
typeof<float>
(fun args -> <@@ g ( f 2 ) @@>)
|> makePropertyStatic
)
|+!> ( provideProperty
"test2" //KO
typeof<int>
(fun args -> <@@ ftype ( Library.SampleModule.Localtype()) @@>)
|> makePropertyStatic
)
)

[<TypeProvider>]
type public CustomTypeProvider(cfg:TypeProviderConfig) as this =
inherit TypeProviderForNamespaces()

do this.AddNamespace("TP", [createTP "TP"])

[<TypeProviderAssembly>]
do()

--程序.fs
   type sampleValue = TP.Outside<""> 

[<EntryPoint>]
let main(args) =
let t = sampleValue.Test //OK
let tt = sampleValue.Test2 //KO

最佳答案

您的程序集可能被加载到不同的 binding context .当引用被反序列化时,它可能会尝试将程序集加载到一个绑定(bind)上下文,即使程序集已经加载到另一个上下文,这种尝试也可能会失败。作为类型提供程序设计时程序集中的解决方法,您可以将处理程序添加到 AssemblyResolve event并尝试在已加载的程序集列表中找到目标程序集。

    do System.AppDomain.CurrentDomain.add_AssemblyResolve(fun _ args ->
let name = System.Reflection.AssemblyName(args.Name)
let existingAssembly =
System.AppDomain.CurrentDomain.GetAssemblies()
|> Seq.tryFind(fun a -> System.Reflection.AssemblyName.ReferenceMatchesDefinition(name, a.GetName()))
match existingAssembly with
| Some a -> a
| None -> null
)

关于visual-studio - 在 F# 中调用另一个 dll 的类型提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10357273/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com