2008-11-05 5 views

답변

31

IronRuby는. NET dll과 이야기하기위한 짧은 작업을하지만 (사실 전혀 코드가 아닐 것입니다.) Microsoft에서 버려졌으며 충분한 오픈 소스 커뮤니티가 없기 때문에 그 사건. 요즘은 추천하지 않겠습니다.

COM 솔루션과 관련하여 실제로는 좋은 방법 일 수 있습니다.

RubyCOM 라이브러리가 필요하지 않습니다. 다른 COM 객체가 루비 코드를 호출 할 수있게합니다. 루비에서 COM 객체를로드하려면 windows ruby에서 표준 라이브러리의 일부로 제공되는 win32ole 라이브러리가 필요합니다.

.NET에서 dll을로드 할 수 있는지 여부는 .NET dll이 'Com Visible'로 작성되었는지에 따라 다릅니다. .NET Framework는 전체 어셈블리 또는 어셈블리 내의 특정 클래스에 적용 할 수있는 ComVisibleAttribute을 정의합니다. 전체 어셈블리 또는 클래스에 대해 true로 설정된 경우 dll은 래퍼 코드없이 COM에서 이미 호출 할 수 있습니다.

다음은 내가 한 테스트입니다.

새 .NET DLL 프로젝트 (클래스 라이브러리)를 만듭니다. 저는 여기에 사용되는 예제 클래스는 다음과 같습니다

using System; 
using System.IO; 

namespace ComLib 
{ 
    public class LogWriter 
    { 
     public void WriteLine(string line) 
     { 
      using(var log = new StreamWriter(File.OpenWrite(@"c:\log.file"))) 
      { 
       log.WriteLine(line); 
      } 
     } 
    } 
} 

지금, 비주얼 스튜디오 프로젝트에서, AssemblyInfo.cs을 포함 Properties라는 디렉토리가있다.이 파일에는 다음이 있습니다.

[assembly: ComVisible(false)] 

false를 true로 변경하십시오. 당신이 COM에 노출 된 어셈블리의 모든 클래스을 원하지 않는 경우에, 당신은 다음과 같이,이 AssemblyInfo.cs false로 설정 그대로두고 대신에 노출 할 각 클래스 이상을 넣을 수 있습니다 :

[ComVisible(true)] 
public class LogWriter .... 

을 지금 dll 프로젝트 자체를 마우스 오른쪽 버튼으로 클릭하고 팝업 메뉴에서 'properties'를 선택하십시오. 섹션 목록에서 Build

아래로 스크롤하여 'COM interop에 등록'체크 박스를 선택하십시오. 이제이 DLL을 컴파일하면 Visual Studio에서 COM 정보를 레지스트리에로드하는 데 필요한 작업을 수행합니다. 비스타를 사용하고 있다면 VS를 관리자로서 실행시켜야합니다.

이제 완료 되었으면 dll을 다시 컴파일 한 다음 새 루비 파일을 만듭니다.

이 루비 파일에서

, 이렇게 : [솔루션 이름] 방금 만든 솔루션의 이름으로 대체 할 수

require 'win32ole' 

lib = WIN32OLE.new('[Solution name].ComLib.LogWriter') 
lib.WriteLine('calling .net from ruby via COM, hooray!') 

(기본 "으로 ClassLibrary1")

루비 그 루비 파일, 그리고 presto! 텍스트가 c:\log.file에 기록됩니다.

이 솔루션의 한 가지 문제점은 .Net DLL이 이미 Com Visible이거나 그렇지 않은 경우 다시 컴파일해야한다는 것입니다. 이 중 어느 것도 사실이 아니라면 다른 옵션을 살펴 봐야 할 수도 있습니다.

행운을 빈다.

+0

감사! dll의 comVisible 속성을 검사하여이 솔루션을 구현할 수 있는지 확인합니다. –

+0

위의 코드를 사용하여 .Net dll 코드에 액세스하고 있지만 대단한 일을하고 있지만이 작업을 닫는 방법을 알고 싶습니다 ...이 코드를 자주 사용하려는 경우 ... 동일한 코드를 사용하면 자주 실행되지 않습니다. 다시 ... 개체를 닫거나 죽일 방법이 있습니까? – Jeyavel

+0

개체를 죽이는 것이 무엇을 의미합니까? .NET 런타임은 COM 개체의 수명을 관리합니다. 가비지 컬렉터가 실행되면 .NET 코드가 COM 객체를 참조하는지 확인하고보고합니다. 그렇지 않으면 COM 객체를 정리합니다. 만약 .NET 코드 * 여전히 * 그것을 참조하는, 다음 그것을 정리하는 오류가 발생합니다. –

0

IronRuby (.Net을 기반으로하는 Ruby 구현)를 사용하는 경우 IronRuby를 사용할 수 있어야합니다. 이미 .Net을 사용하고 있고 Ruby를 사용해보고 싶다면 IronRuby를 조사하고 싶을 것입니다.

IronRuby 바깥 쪽 확실하지 않습니다. Ruby를 직접 사용하지 않았기 때문에 어떤 종류의 기능이 가능한지 알지 못합니다.

2

당신은 당신이 COM을 통해 갈 수 있습니다 (나는 아이언 루비가 아직 완전히의 RoR을 실행하는 것 같아요 이후) '정상'루비를 사용하려는 경우 - 즉, 조금 복잡한의

"Your Ruby Code" -> RubyCOM -> "COM-Callable Wrappers" -> "Your .NET objects" 

RubyCom

그래도.

편집 : 다른 답변

1

또 다른 것은 더 나은 COM 기반 옵션은 - 더 많은 서비스 지향 아키텍처 관점에서 그것에 대해 생각하는 것이 더있을 수 있습니다. .NET DLL을 가져 와서 서비스로 공개 할 수 있습니까?

뒷 배경에서 C로 Ruby 모듈을 작성할 수 있으므로 필요한 작업을 수행하기 위해 언제든지 interop을 작성할 수 있습니다. 하지만 Windows 플랫폼으로 배포하는 데는 한계가 있습니다. (Ruby-> Interop-> Mono를 시도하지 않았습니다)

여기에 Ruby for C# Developers이라는 몇 년 전에 발표 한 프레젠테이션이 있습니다. 조금 오래되었습니다 (John Lam의 프로젝트가 IronRuby로 접어 들기 전 이었지만). 조금 도움이 될 수 있습니다.

+0

루비 에서 해당 DLL을 호출 갈 수있는 방법입니다 SOA 서비스로 .NET DLL을 노출하는 FFI를 사용하지만, 나는이 일의 보안 문제를 확인해야합니다. –

0

AFAIK는 죽은 프로젝트이지만, John Lam (누가 IronRuby를 담당하고 있는지)이 흥미로운 내용으로 이전 RubyCLR project을 찾을 수 있습니다.

3

-> C# 래퍼 DLL 관리 사용하여 C++

내보내기 모든 기능을 C는 DLL에서, 예를 들어, 전화로 당신이 원하는

extern "C" __declspec (dllexport) void CallManagedMethod() { 
    Something^ myManagedObject ... 
} 

그런 다음 https://github.com/ffi/ffi

관련 문제