2010-08-04 80 views
4

我正在使用jni4net从C#应用程序中访问Java代码,反之亦然。 jni4net使用反射来生成JNI代理代理,所以显然其中一个限制是您的Java和C#代码必须编译才能构建代理。用jni4net传递的双向对象(是:忽略缺少的类)

不幸的是,这可能会导致一个catch-22问题。试想一下:

C#类X使用Java Y类
的Java Y类使用C#类X

两者都不能编译,所以完善的解决办法是采取类(X或Y)之一,将其剥离到其裸露的签名并将其编译,然后从编译的框架生成代理。然后你可以用原文替换剥离的类,然后继续快乐的方式。

这对我来说好像很难看,我相信应该有更好的方法。一个明显的解决方案是告诉编译器(无论是C#还是Java,其中哪一个)忽略对缺少的类的引用。

是否忽略了对C#或Java编译器可行的某种缺失类的引用?有没有更好的方法来做到这一点(不,我不打算考虑套接字或任何性质的东西;我需要.NET和Java之间的真正互操作)?请求

示例代码:

实施例的代码为清楚起见移除jni4net桥接代码。 IA和IB是简单的接口,也不包括在内。

的Java:

public class A implements IA 
{ 
    public void m1() 
    { 
     System.out.println("m1 called"); 
    } 

    public static void main (String args[]) 
    { 
     IB b = new B(); 
     b.m2(new A()); 
    } 
} 

C#:

public class B : IB 
{ 
    public void m2(IA a) 
    { 
     a.m1(); 
     A a2 = new A(); 
     a2.m1(); 
    } 
} 

回答

4

我最终自己解决了这个问题。这不涉及我最初的预感,所以我改变了这个问题的标题,以更好地反映实际问题。

虽然jni4net软件包有很多有用的例子,但似乎没有任何好的显示在没有一些奇怪的构建操作的情况下在两个方向上传递对象(请参阅原始问题声明)。我想出了如何做到这一点,并将解决方案与创建结果所需的命令一起展示。

让这个运行最简单的方法是按照指令说明设置jni4net并将所有这些东西放到jni4net软件包附带的示例目录的新子目录中。

首先C#代码:

的src /测试/左。CS

namespace test 
{ 
    using System; 
    using net.sf.jni4net; 
    using test; 

    public class left : iright 
    { 
     public static void Main(String[] args) 
     { 
      left l = new left(); 
      l.sendMeToRight(); 
     } 

     public left() 
     { 
      Console.WriteLine("left side constructed..."); 
     } 

     public void sendMeToRight() 
     { 
      BridgeSetup bridgeSetup = new BridgeSetup(); 
      bridgeSetup.AddAllJarsClassPath("."); 
      Bridge.CreateJVM(bridgeSetup); 
      Bridge.RegisterAssembly(typeof(right).Assembly); 

      Console.WriteLine("Sending myself to right."); 
      right il = new right(this); 
      il.announceMyself(); 
     } 

     public void announceMyself() 
     { 
      Console.WriteLine("Hello from the left side..."); 
     } 
    } 
} 

而现在的Java代码:

的src /测试/ iright.java

package test; 

public interface iright 
{ 
    void announceMyself(); 
} 

的src /测试/ right.java

package test; 

public class right implements iright 
{ 
    public right(iright f) 
    { 
     System.out.println("right side constructed... "); 
    f.announceMyself(); 
    } 

    public void announceMyself() 
    { 
     System.out.println("Hello from the right side..."); 
    }  
} 

最后构建s cript(我建立它在cygwin中运行,并在很短的时间内通知,根据需要进行修改):

@echo off 
rm -rf build 
mkdir build 
mkdir build\test 
copy ..\..\lib\*.* build 

echo Compile base classes. 
javac src/test/*.java 
mv src/test/*.class build/test 

echo Creating jar file. 
jar cvf build\lr.jar -C build test/iright.class -C build test/right.class 
rm build/test/*.class 

echo Generating proxies. 
..\..\bin\proxygen.exe build\lr.jar -wd build 

echo Compiling derived proxy classes. 
javac -cp build\lr.jar;build\jni4net.j-0.8.0.0.jar build\jvm\test\iright_.java build\jvm\test\right_.java 

echo Packing compiled derived proxy classes. 
jar cvf build\lr.j4n.jar -C build\jvm test\__iright.class -C build\jvm test\iright_.class -C build\jvm test\right_.class 

echo Generating derived proxy DLL. 
cd build 
csc.exe /nologo /warn:0 /t:library /out:lr.j4n.dll /recurse:clr\*.cs /reference:"c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll" /reference:jni4net.n-0.8.0.0.dll 

echo Generating product executable. 
csc.exe /nologo /warn:0 /out:demo.exe /target:exe /reference:jni4net.n-0.8.0.0.dll /reference:lr.j4n.dll ..\src\test\left.cs 
+1

构建体操仍然存在,您只需使用构建脚本将它们自动化即可。 – Hassan 2014-12-28 23:41:17

0

在C#4你也许能够访问Java对象时要使用的动态关键字。没有完全尝试过你的场景。一些示例代码会有所帮助。

编辑更新的问题
你有一个循环依赖一个单一的编译器可能会抱怨,更别说是两位。重构更类似于以下内容将有所帮助。当然,在你真实的代码中可能不会那么简单。

// java 
public class A implements IA 
{ 
    public void m1() 
    { 
     System.out.println("m1 called"); 
    } 
} 

public class MainClass 
{ 
    public static void main (String args[]) 
    { 
     IB b = new B(); 
     b.m2(new A()); 
    } 
} 

//C# 

public class B : IB 
{ 
    public void m2(IA a) 
    { 
     a.m1(); 
     A a2 = new A(); 
     a2.m1(); 
    } 
} 
+0

查看我刚刚添加的示例代码。 – 2010-08-05 00:43:38

+0

是的,我不确定这是否适合我的用例,但它仍然是一个有趣的方法。 – 2010-08-05 23:45:09