J ++到J#:如何转换资源?

时间:2017-01-27 17:56:37

标签: .net embedded-resource j# j++ visualj#

我有一个 Visual J ++ 项目,我想迁移到 J#。代码不使用任何Microsoft特定的API(如 WFC )或非标准语言扩展,因此从技术上讲,它完全符合Java 1.1。

唯一的问题是资源(在Java世界中通常使用Class.getResourceAsStream() API访问)。

J ++ 中,在项目配置中指定资源文件名模式就足够了,模式匹配的所有资源都会嵌入到生成的* .exe中(作为本机Win32资源)并使用Class.getResourceAsStream()以编程方式访问,并使用任何resource editor手动访问:

enter image description here

问题

项目迁移到 Visual J#(VS 2005)后,我立即失去了加载任何资源的能力(Class.getResourceAsStream()开始返回null值),尽管"构建行动"设置被设置为"嵌入式资源"对于每个感兴趣的资源:

enter image description here

并且资源实际嵌入到程序集中(可以通过增加的* .exe文件大小来确认;另外,我确实使用dotPeek工具查看了这些资源)。使用以下模式生成唯一资源名称:

<assembly's default namespace>.<Java package>.<file name with extension>

因此,如果我在README.txt包下嵌套了名为com.example的文件,则生成的程序集资源名称将为default.com.example.README.txt

dotPeek

Visual Studio 2003 的行为与2005版本不同:Class.getResourceAsStream()不会返回任何null,但ArgumentOutOfRangeException会引发mscorlib.dll在运行时:

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

- 但我相信这只是2.0版本的 .NET Framework 中修复的错误。

com.ms.vjsharp.lang.VJSClassLoader显然对我来说不是一个公共课程,可以直接使用它。

尝试解决方法

  1. 用绝对值替换相对资源路径,用斜杠替换相反的点,用或不用前导斜杠,或者没有前缀的默认程序集名称空间 - 没有效果。
  2. 使用javac编译器将整个项目编译为可执行文件* .jar,并将生成的JAR提供给 J#Binary Converter Tool jbimp.exe) - 不是一种选择。 J#Binary Converter Tool 由于其局限性而几乎无用(我试过两个版本 - 来自VS 2003和VS 2005):

    • 在Java字节码中对Class.getResourceAsStream(...)进行单次调用会导致System.InvalidProgramException在运行时抛出,尽管MSIL转换的字节码成功。
    • 每当有一个try-finally块(这是通常在 Java 中完成流I / O的方式)时,jbimp.exe会失败并显示这些消息(我给了尝试重写仅仅从文件中读取的5行代码块:

      JbImp error: Internal Conversion Error : 'exc-unclosed-blocks'
      JbImp error: Failed to create type for class 'com/example/Main'. Creating stub type
      JbImp error: Internal Conversion Error : 'JbImp fatal error: Conversion failed'
      
  3. 来自VS 2003/2005的
  4. J ++项目迁移向导没有帮助:它只是忽略未从*.rc / *.res文件引用的任何资源。

  5. 手动创建*.resx文件,向其添加所有资源并完全删除Class.getResourceAsStream()调用(更改Java代码以将资源加载为System.String(对于文本)和{{ 1}}(用于图像))。这是唯一可行的方法,但如果您的项目中有几十个小System.Drawing.Bitmap个文件,那就变得非常繁琐。
  6. 问题

    为什么*.gif vjslib.dll的实施工作没有按预期进行?我在这里缺少什么?

1 个答案:

答案 0 :(得分:0)

Microsoft J#运行时中实现的 Java API的文档很模糊(特别是Class.getResourceAsStream()个州的页面与 J ++ 不同, J#中不支持此方法,解决方案。

进一步研究表明,除了自定义class loaders(已被删除)之外,所有 Java 1.1 甚至一些 Java < / em> 1.2 API已经实施 - 包括collectionsSwing

说到资源How to: Upgrade Visual J++ 6.0 Applications That Use Resources文章涵盖了这些内容。可以使用 Visual Studio 2005 应用程序示例附带的vjsresgen.exe实用程序将 Java 样式资源转换为.resx,源代码可从< EM>微软

每个资源都转换为字节数组。以下是在 Visual Studio 中打开的示例vjsresgen.exe生成的.resx文件的屏幕截图:

vjsresgen.exe-generated .resx file