문제

First_Layer

VC ++ 6 서비스 팩 6에 Win32 DLL이 작성되었습니다. FirstLayer의 소스 코드에 액세스 할 수는 없지만 관리 코드에서 호출해야합니다. 문제는 FirstLayer가 std :: vector 및 std :: string을 함수 인수로 크게 사용하고 이러한 유형을 C# 응용 프로그램으로 직접 마샬링하는 방법이 없다는 것입니다.

Second_layer

내가 생각할 수있는 솔루션은 먼저 VC ++ 6 서비스 팩으로 작성된 또 다른 Win32 DLL을 만드는 것입니다. SecondLayer는 FirstLayer의 래퍼 역할을합니다. 이 레이어에는 std :: 벡터에 대한 래퍼 클래스가 포함되어 있으므로 STD :: 벡터는이 레이어의 모든 함수 매개 변수에 노출되지 않습니다. std :: 벡터를 위해이 래퍼 클래스를 stdvectorwrapper로 부르겠습니다.

이 레이어는 STD :: 벡터가 내부적으로 처리되므로 메모리를 할당하거나 거래하는 새 또는 삭제 작업을 사용하지 않습니다.

Third_Layer

또한 두 번째 레이어의 래퍼로 VC ++ 2005 클래스 라이브러리를 만들었습니다. 이 래퍼는 관리되지 않는 2 학년을 관리 코드로 변환하는 모든 더러운 작업을 수행합니다. 이 레이어를 "Thirdlayer"라고합시다.

Secr

Fourth_Layer

무엇보다도, 나는 C#2005 콘솔 애플리케이션을 만들어 ThirdLayer를 호출했습니다. 이 C# 콘솔 응용 프로그램을 "Fourthlayer"라고합시다.

호출 시퀀스 요약

Fourthlayer (C#2005) -> ThirdLayer (VC ++ 2005) -> SecondLayer (VC ++ 6) -> FirstLayer (VC ++ 6)

문제

나는 "System.AccessViolationException : 보호 된 메모리를 읽거나 쓰려고 시도했습니다"예외는 제외하고, 제 3 회에 액세스 할 수있는 불법 인 제 2 회 내부 STD :: 벡터 할당 메모리로 인한 것으로 생각됩니다.

VC ++ 2005의 FirstLayer (시뮬레이션)와 2 차 계층을 다시 컴파일 할 때 문제가 완전히 사라지기 때문에 이것은 생각됩니다. 그러나 소스 코드가 없으므로 FirstLayer의 프로덕션 버전을 다시 컴파일하는 것은 불가능합니다.

이 문제를 없애려면 stdvectorWrapper 클래스에서 발견되는 2llayer의 std :: vector를 위해 c ++에 공유 메모리 할당자를 작성해야한다고 들었습니다. 공유 메모리 할당이 필요한 이유와 작동 방식을 완전히 이해하지 못합니까? 아이디어가 있습니까?

인터넷에서이를 위해 쉽게 사용할 수있는 소스 코드가 있습니까?

이를 위해 부스트 라이브러리를 사용할 수 없습니다.

도움이 되었습니까?

해결책 3

문제에 대한 해결책을 찾았습니다. 기본적으로, 내가 쓴 stdVectorWrapper 클래스는 딥 카피를 구현하지 않습니다. 따라서 Deep Copy를 구현하기 위해 STDVECTERWPRAPPER 클래스에 다음을 추가하는 것입니다.

  • 생성자 복사
  • 과제 연산자
  • 해체 조치

편집 : 대체 솔루션

더 나은 솔루션은 사용하는 것입니다 clone_ptr std :: 벡터에 포함 된 모든 요소와 std :: 벡터 자체에 대해. 이는 카피 생성기, 할당 연산자 및 해체가 필요하지 않습니다.

다른 팁

각 실행 파일 또는 DLL 링크는 C 런타임 라이브러리의 특정 버전으로 링크합니다. 여기에는 구현이 포함됩니다. new 그리고 delete. 두 모듈에 다른 컴파일러 (VC2005 vs VC6) 또는 빌드 설정 (디버그 대 릴리스) 또는 기타 설정 (멀티 스레드 런타임 vs 비일 리드 스레드 런타임)이있는 경우 다른 C 런타임에 연결됩니다. 한 번의 런타임에 의해 할당 된 메모리가 다른 런타임으로 해제되는 경우 문제가됩니다.

이제 실수하지 않으면 템플릿 (예 : std :: vector 또는 std :: string)으로 인해이 문제가 즉시 명백하지 않은 곳에 몰래 들어갈 수 있습니다. 문제는 템플릿이 각 모듈에 별도로 컴파일된다는 사실에서 비롯됩니다.

예 : 모듈 1은 벡터 (따라서 메모리 할당)를 사용한 다음 기능 매개 변수로 모듈 2로 전달한 다음 모듈 2는 벡터를 조작하여 메모리가 처리되게합니다. 이 경우 모듈 1의 런타임을 사용하여 메모리를 할당하고 모듈 2의 런타임을 사용하여 거래했습니다. 이러한 런타임이 다르면 문제가 있습니다.

따라서 모든 것을 감안할 때 잠재적 인 문제에 대한 두 곳이 있습니다. 하나는 두 모듈이 정확한 동일한 설정. 다른 하나는 Secondlayer와 If가 3 라일 사이에 있습니다 어느 메모리는 하나에 할당되고 다른 하나는 거래됩니다.

어떤 장소에 문제가 있는지 확인하기 위해 몇 가지 테스트 프로그램을 더 작성할 수 있습니다.

FirstLayer-SeconDlayer를 테스트하려면 SecondLayer 함수의 구현을 VC6 프로그램에 복사하고 일반적인 방식으로 해당 함수를 호출 할 수있는 충분한 코드 만 작성하고 FirstLayer에 대해서만 연결하십시오.

해당 첫 번째 테스트가 실패하지 않거나 다른 일단 수정 된 경우 SecondLayer-Thirdlayer를 테스트하십시오. ThirdLayer 구현을 VC2005 프로그램에 복사하고 일반적인 호출을 위해 코드를 작성하고 SecondLayer에 연결하십시오.

다른 솔루션 아키텍처를보아야한다고 생각합니다.

VC6 STL 벡터 및 문자열에 의해 생성 된 이진 코드는 많은 STL 업그레이드로 인해 VC의 최신 버전에서 생성 된 코드와 다릅니다. 이로 인해 DLLS는 이진 호환되지 않은 STD :: Vector와 STD :: String의 두 가지 구현을 갖기 때문에 아키텍처가 작동하지 않을 것이라고 생각합니다.

제안 된 솔루션은 VC6으로 돌아가서 순수한 C API를 통해 노출되는 FirstLayer에 대한 새로운 래퍼 DLL을 작성하는 것입니다.이 레이어는 vc6sp6을 사용하여 컴파일되어야합니다. 그런 다음 Fourth_Layer에서 Pinvoke를 사용하여 VC6 래퍼 DLL에 액세스하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top