当在没有regasm的codebase选项的情况下注册COM时,对C#COM的javajni调用失败

当在没有regasm的codebase选项的情况下注册COM时,对C#COM的javajni调用失败,c#,java,java-native-interface,c++-cli,C#,Java,Java Native Interface,C++ Cli,当C#COM未使用regasm和codebase选项注册时,通过JNI-C++/CLI从Java到C#的函数调用失败。我按照中的说明构建了一个示例,并做了一些更改 第一名:C# 通过创建接口,IRunner,并使库程序集COM可见,将C#dll更改为COM 截止日期:Java 没有对Java部分进行任何更改 数字:C++ 此部分已更改为创建RunnerCOM.Runner类的新实例并使用该结果。下面是一个关于如何从非托管代码调用托管代码的好教程: Codebase在注册表中创建一个Codebas

当C#COM未使用regasm和codebase选项注册时,通过JNI-C++/CLI从Java到C#的函数调用失败。我按照中的说明构建了一个示例,并做了一些更改

第一名:C#

通过创建接口,
IRunner
,并使库程序集COM可见,将C#dll更改为COM

截止日期:Java 没有对Java部分进行任何更改

数字:C++

此部分已更改为创建
RunnerCOM.Runner
类的新实例并使用该结果。下面是一个关于如何从非托管代码调用托管代码的好教程:

  • Codebase在注册表中创建一个Codebase条目。代码库条目为未安装在全局程序集缓存中的程序集指定文件路径,因此当您指定代码库时,系统将根据该路径查找DLL。如果没有,它将尝试在GAC和当前工作目录中定位dll。在JNI中,我认为当前工作目录不是DLL所在的文件夹。您可以使用查找当前工作目录,也可以使用查找exe正在查找的目录来查找dll

  • 将_bstr_t转换为char*的代码中,char*字符串的上限没有以“\0”结尾,我认为这可能会导致JNI出现问题。使用_bstr_t运算符(char*),可以从_bstr_t对象获取以null结尾的字符串。请查看详细信息

  • 您提到了C++/CLI、C++/CLI和COM warpper是与C#代码互操作的两种不同方式。如果使用C++/CLI作为桥接器,则不需要将C#DLL注册为COM,请参见以下内容:


    如果您使用的是COM,您应该在代码中首先调用init COM。

    我正在寻找更具体的答案和参考资料。例如,我对问题1做出了与您相同的假设。加载期间,它会在system32文件夹中查找dll,但工作目录已正确初始化(只是不知道为什么不在那里查找)。对于第二个答案,到char*的转换应该如我所描述的那样工作。不过谢谢你的其他观点。
    namespace RunnerCOM
    {
        public interface IRunner
        {
            String ping();
        }
        public class Runner:IRunner
        {
            static void Main(string[] args)
            {
            }
            public Runner() { }
            public String ping()
            {
                return "Alive (C#)";
            }
        }
    }
    
    #include "stdafx.h"
    #include "Runner.h"
    #pragma once
    #using <mscorlib.dll>
    #import "RunnerCOM.tlb"
    
    JNIEXPORT jstring JNICALL Java_Runner_ping(JNIEnv *env, jobject obj){
        RunnerCOM::IRunnerPtr t = RunnerCOM::IRunnerPtr("RunnerCOM.Runner");
        BSTR ping = t->ping();
    
        _bstr_t temp(ping, true);
    
        char cap[128];
        for(unsigned int i=0;i<temp.length();i++){
            cap[i] = (char)ping[i];
        }
    
        return env->NewStringUTF(cap);
    }
    
    int main(){
        RunnerCOM::IRunnerPtr t = RunnerCOM::IRunnerPtr("RunnerCOM.Runner");
        BSTR ping = t->ping();
    
        _bstr_t temp(ping, false);
    
        printf(temp);
        return 0;
    }