2011-01-17 1 views
1

VC++ 6로 작성된 오래된 ocx (spectrograph.ocx)가 있습니다. 나는이 오래된 OCX 컨트롤을 사용하여 새 C# .NET을의 Win32 응용 프로그램을 작성하는 것을 시도하고있다float 배열을 C#에서 vC++로 작성된 ocx로 전달합니다.

afx_msg void AppendDataX(float FAR* data, long n, float xpos); 

: 그것은 다음과 같이 정의된다 AppendDataX (라는 방법)이 포함되어 있습니다. AxSPECTROGRAPHLib.dll을 생성하기 위해 다음 명령을 사용했습니다.

AxImp spectrograph.ocx 

나는 다른 컨트롤처럼 폼에 추가 할 수있는 IDE (SharpDevelop)에 컨트롤 (새로 만든 .dll을 통해)을 가져올 수 있습니다. 지금까지 너무 좋아, 나는 OCX 방법 AppendDataX()에 플로트 []를 전달하려고 때까지 나는 MSIL 디스어셈블러를 사용했다

Argument '1': cannot convert from 'float[]' to 'ref float' (CS1503) 

:

 FileStream tw = new FileStream("XX-YY-ZZZZ.2011.01.10.15.52.00.spec", FileMode.Open); 
     BinaryReader br = new BinaryReader(tw); 
     int pixelCnt = br.ReadInt32(); 
     float[] wavelength = new float[pixelCnt]; 
     for (int i=0; i<pixelCnt; i++) 
      wavelength[i] = br.ReadSingle(); 

     bool eof = false; 
     float temp; 
     float[] spectrum = new float[pixelCnt]; 
     while(!eof) 
     { 
      try 
      { 
       temp = br.ReadSingle(); 
       for (int i=0; i<pixelCnt; i++) 
        spectrum[i] = br.ReadSingle(); 

       spec.AppendDataX(spectrum, pixelCnt, temp); 
      } 
      catch(EndOfStreamException) 
      { 
       eof = true; 
      } 
     } 
     tw.Close(); 

이 컴파일시에 다음과 같은 오류가 발생합니다 AxSPECTROGRAPHLib.il를 생성하고 I 얻을이 : I 검색 및 VC6 ++ OCX에 C 번호로부터 float []로부터 마샬링 보여주는 간단한 예를 검색 왔지만

.method public hidebysig newslot virtual 
     instance void AppendDataX(float32& data, 
           int32 n, 
           float32 xPos) cil managed 
{ 
// Code size  35 (0x23) 
.maxstack 8 
IL_0000: ldarg.0 
IL_0001: ldfld  class [SPECTROGRAPHLib]SPECTROGRAPHLib._DSpectrograph AxSPECTROGRAPHLib.AxSpectrograph::ocx 
IL_0006: brtrue.s IL_0014 

IL_0008: ldstr  "AppendDataX" 
IL_000d: ldc.i4.0 
IL_000e: newobj  instance void [System.Windows.Forms]System.Windows.Forms.AxHost/InvalidActiveXStateException::.ctor(string, 
                                 valuetype [System.Windows.Forms]System.Windows.Forms.AxHost/ActiveXInvokeKind) 
IL_0013: throw 

IL_0014: ldarg.0 
IL_0015: ldfld  class [SPECTROGRAPHLib]SPECTROGRAPHLib._DSpectrograph AxSPECTROGRAPHLib.AxSpectrograph::ocx 
IL_001a: ldarg.1 
IL_001b: ldarg.2 
IL_001c: ldarg.3 
IL_001d: callvirt instance void [SPECTROGRAPHLib]SPECTROGRAPHLib._DSpectrograph::AppendDataX(float32&, 
                           int32, 
                           float32) 
IL_0022: ret 
} // end of method AxSpectrograph::AppendDataX 

I는 F하지 않은 ound 예제는 아직 나를 위해 작동합니다. 누군가가 올바른 방향으로 나를 이끌 수 있도록 도와 줄 수 있습니까? 나는 옳은 길을 가고있는 것 같아요. 그렇게하기가 힘들지는 않겠지 만, 며칠 동안 이것을보고 난 후에 붙어있는 것처럼 느껴집니다. .

답변

0

컨트롤이 그대로 첫 번째 요소의 주소를 원하는 글쎄, 당신은 항상 핀과 주소를 반환 할 수 있습니다

문제의
var handle=GCHandle.Alloc(spectrum, GCHandleType.Pinned); 
unsafe 
{ 
    float *val=(float *)handle.AddrOfPinnedObject(); 
    // here's the val to send to your object 
} 
handle.Free(); 
+0

첫 번째 요소 이상에 액세스해야하므로 불행히도 이것이 작동하지 않을 것이라고 생각합니다. – Tim

+0

내가 따르지 않을거야, 당신은 항상 첫 번째 요소에 대한 포인터로 전체 배열에 액세스 할 수 있습니다. – Blindy

1
afx_msg void AppendDataX(float FAR* data, long n, float xpos); 

, 즉 자동화 호환 함수 서명이 아니다. 배열은 SafeArray로 전달되어야하며 함수는 HRESULT를 반환해야합니다. 현재 형식 라이브러리 임포터는 첫 번째 인수가 배열임을 추측 할 방법이 없으며 단일 float 값에 대한 포인터 일 수도 있습니다. 그것은 추측 한 것이고, ref는 떠 다닙니다.

네이티브 코드를 변경할 수없는 경우 기술적으로 interop 라이브러리를 편집하고 float []를 사용하도록 서명을 변경할 수 있습니다. 그것의 당신의 분해는 매우 이상한 btw, 결코 전에 보지 못했습니다. CLR은 일반적으로 interop 라이브러리의 함수 선언에서 동적으로 COM 스텁을 생성합니다. 당신이 게시 한 것을 어떻게 얻었는지 실마리가 없습니다.

기술적으로 모듈 내보내기를 형식 라이브러리로 가져올 수 있습니다. 그러나 그것은 이 아니고 인 OCX입니다. 그러나 비 자동화 호환 서명과 IL 스텁을 설명합니다. 이 경우 형식 라이브러리를 사용하는 대신 내 보낸 함수를 직접 사용하는 작은 C++/CLI ref 클래스 래퍼를 만드는 것이 더 쉽습니다. 배열을 float *로 변환하는 것은 pin_ptr <>을 사용하면 쉽습니다.

0

최근에이 문제가 발생했습니다. 그리고 HERE 해결책을 찾았습니다. SAFEARRAY 유형으로 실제 함수를 호출하는 도우미 DLL 작성.

ocx 컨트롤의 소스에 액세스 할 수 있으므로 해결 방법을 시도하지 않았 음을 유의하십시오. 포인터 매개 변수를 SAFEARRAY 유형으로 수정하기 만합니다. 그리고 그렇게하려면 HERE이 상세한 예입니다.

HERE에 설명 된 것처럼 InterOP 클래스의 IL을 수정하고 다시 컴파일하려고했지만 그 방법이 저에게 효과적이지 않습니다. 나는 그것을 잘못 할 수있다.

나는 당신과 마찬가지로이 문제로 미친 듯이 운전 했으므로 빠져 나올 수 있기를 바랍니다.

관련 문제