我有一个VisualJ++项目,我想迁移到J#。代码不使用任何特定于微软的API (如WFC)或非标准语言扩展,因此,在技术上,它完全符合Java1.1。
唯一的问题是资源(在Java中,资源通常是使用Java访问的)。
在J++中,只要在项目配置中指定资源文件名模式就足够了,所有由模式匹配的资源都会嵌入到生成的*.exe (作为本机Win32资源)中,并通过编程方式使用Class.getResourceAsStream()和手动使用任何资源编辑器进行访问。

问题所在
项目迁移到VisualJ# (VS 2005)后,我立即失去了加载任何资源的能力(Class.getResourceAsStream()开始返回null值),尽管“构建操作”设置设置为“嵌入式资源”,用于每个感兴趣的资源:

这些资源实际上被嵌入到程序集中(可以通过增加的*.exe文件大小来确认;此外,我确实看到这些资源使用dotPeek工具)。使用以下模式生成唯一的资源名称:
<assembly's default namespace>.<Java package>.<file name with extension>
因此,如果我有一个名为README.txt的文件嵌套在com.example包下,则生成的程序集资源名称将是default.com.example.README.txt。

Visual 2003的行为与2005年版本不同:Class.getResourceAsStream()不返回任何null,但在运行时由mscorlib.dll引发ArgumentOutOfRangeException:
mscorlib.dll!System.String.Substring(int startIndex = 0, int length = -1) + 0xbb bytes
vjslib.dll!com.ms.vjsharp.lang.VJSClassLoader.__findResource(System.Reflection.Assembly currentAssembly = {System.Reflection.Assembly}, string resName = "com/example/README.txt") + 0xc5 bytes
vjslib.dll!com.ms.vjsharp.lang.VJSClassLoader.__getResourcefromAssembly(System.Reflection.Assembly callingAssembly = {System.Reflection.Assembly}, string resName = "com.example.Main/+/com/example/README.txt") + 0x1b7 bytes
vjslib.dll!com.ms.vjsharp.lang.VJSClassLoader.getResourceAsStream(string resName = "com.example.Main/+/com/example/README.txt") + 0x57 bytes
vjslib.dll!java.lang.Class.getResourceAsStream(string resourceName = "com.example.Main/+/com/example/README.txt") + 0x10d bytes
test-resource-loading.exe!com.example.Main.main(String[] args = {Length=0}) Line 21 + 0x26 bytes--但我相信这只是.NET框架2.0版本中的一个错误。
显然,对于我来说,com.ms.vjsharp.lang.VJSClassLoader不是一个可以直接使用它的公共类。
解决办法
javac,并将得到的JAR提供给J#二进制转换器工具(jbimp.exe) --这不是一个选项。由于J#二进制转换器工具的局限性,它几乎毫无用处(我尝试了这两个版本-来自VS 2003和VS 2005):- a single call to `Class.getResourceAsStream(...)` in Java bytecode results in `System.InvalidProgramException` thrown at runtime, despite bytecode to MSIL conversion is successful.
- whenever there's a try-finally block (which is how stream I/O is usually done in _Java_), `jbimp.exe` fails with these messages (I gave up trying to rewrite the 5-line block of code which was merely reading from a file):JbImp错误:内部转换错误:‘exc-未关闭块’JbImp错误:未能为类“com/JbImp/Main”创建类型。创建存根类型JbImp错误:内部转换错误:“JbImp致命错误:转换失败”
*.rc/*.res文件中引用的任何资源。*.resx文件,向其添加所有资源,并完全消除Class.getResourceAsStream()调用(将Class.getResourceAsStream()代码更改为将资源加载为System.String (用于文本)和System.Drawing.Bitmap (用于图像))。这是唯一的工作方法,但是如果您的项目中有几十个小*.gif文件,那么它将变得非常乏味。问题是
为什么vjslib.dll的Class.getResourceAsStream()实现不能像预期的那样工作呢?我在这里错过了什么?
发布于 2017-03-24 11:13:50
虽然在J#运行时中实现的是模糊的(特别是,Class.getResourceAsStream()的页面声明,与J++不同,该方法在J#中不受支持),但有一个解决方案。
进一步的研究表明,除了定制的类装入器 (已经被删除)之外,所有的1.1,甚至一些Java 1.2 API都已经实现--包括https://msdn.microsoft.com/en-us/library/abw7x2tf(v=vs.80).aspx和https://msdn.microsoft.com/en-us/library/k12dt1e0(v=vs.80).aspx)。
说到资源,如何:升级使用资源的VisualVISUAL6.0应用程序文章介绍了这些资源。可以使用Visual 2005应用程序示例附带的.resx实用工具将Java风格的资源转换为vjsresgen.exe,并提供微软的源代码。
每个资源被转换成一个字节数组。下面是在Visual中打开的示例vjsresgen.exe-generated .resx文件的屏幕截图

https://stackoverflow.com/questions/41900175
复制相似问题