Recent Posts
Recent Comments
Link
관리 메뉴

NaggingMachine

Failure on Activator.CreateInstance (Activator.CreateInstance 의 실패) 본문

TechnoBabbler

Failure on Activator.CreateInstance (Activator.CreateInstance 의 실패)

naggingmachine 2007. 1. 10. 17:16

I needed to create Direct Show filters by using Activator.CreateInstance, and it always failed on my machine(x64). It, however, worked on my another machine(x86). To make the situation more clearly, I tried several test projects like followings.

1) Native C++ project which use native COM functions. -> :-)

2) 32bit .NET project which use Activator.CreateInstance --> :-)

3) 64bit .NET project which use Activator.CreateInstance --> :-(

I was not sure that at least I found the problem is related with processor. But you know, I was using .NET and I thought it could not be a problem whether the platform is 32bit or 64bit. However, I found it could affect the result of Activator.CreateInstance. I settled down the problem by setting the project build configuration as a x86 machine. Open the project properties window and select build tab. Change the platform target into x86 on the right panel and rebuild all your project. That's all.

* Sample Code

private IBaseFilter LoadFilter(Guid filterClsid, string name)
{
Type type1 = null;
object obj1 = null;
type1 = Type.GetTypeFromCLSID(filterClsid);
if (type1 == null)
{
throw new ApplicationException(name + " not installed");
}
obj1 = Activator.CreateInstance(type1); // Failed
IBaseFilter filter1 = (IBaseFilter)obj1;
obj1 = null;
int num1 = this.graphBuilder.AddFilter(filter1, name);
if (num1 < 0)
{
Marshal.ThrowExceptionForHR(num1);
}
return filter1;
}

얼마전 시작한 프로젝트에서 Direct Show 필터를 연결하여 동영상을 플레이해야 했다. .NET 프로젝트 였기 때문에 Activator.CreateInstance 메서드를 이용하여 필터 객체를 생성하는 것이었는데, 어찌된 일인지 저 메서드가 계속해서 실패하는 것이었다. 물론 메서드의 매개 변수로 사용하는 컴포넌트의 CLSID는 등록이 되어 있었음은 물론, GraphEdit를 사용하여 필터를 연결했을 때 아무런 문제가 없는 시스템 환경이었다. 시스템을 좀더 테스트하기 위해서 32비트 머신에서 프로그램을 돌려 보았는데, 아니 왠걸, 잘 작동하는게 아닌가? 64비트 머신이기 때문에? 일단 문제점을 좀더 정확하게 파악하기 위해서 간단한 테스트 프로그램을 만들어 보았다.

1) 네이티브 C++ 프로젝트 (네이티브 COM 함수 사용) --> 작동
2) 32비트 .NET 프로젝트 (Activator.CreateInstance 메서드 사용) --> 작동
2) 64비트 .NET 프로젝트 (Activator.CreateInstance 메서드 사용) --> 실패

1번과 2번이 성공했기 때문에 컴포넌트 문제는 아닌것 같고, 결국 32비트와 64비트의 차이라는 것을 알게 되었다. 하지만 .NET의 모토가 바로 가상화 아니던가! 어떤 버전을 사용하더라도 문제없이 돌아가도록 만들어주는게 바로 .NET 일텐데, 설마 32비트와 64비트에 차이가 있을까? 라고 굳게 믿고 있었는데, 사실 문제는 바로 .NET에 있었다. 어찌된 일인지 .NET에서 64비트로 컴파일하면 System32 폴터에 설치되어 있는 필터들은 잘 로드하는 반면, SysWow64 폴더에 있는 필터들은 로드를 하지 못했다. 왜! 왜! 이유는 나도 모르겠고, 그래서 혹시나 하는 마음에 프로젝트 환결 설정에 가서 64비트 호완 모드가 아닌 x86, 그러니까 32비트 호환 모드로 변경해서 다시 빌드를 해보았더니 프로그램이 잘 작동했다. 한편 이 문제는 비단 나의 코드 뿐만 아니라 비슷한 코드를 사용하는 다른 프로그램에서도 동일하게 발생된다는 사실. 다행인지 불행인지 삽질을 통해서 좋은 거 배웠다. 문제를 해결하기 위한 방법을 단계적으로 설명하자면, 우선 프로젝트 구성 정보 창을 띄운 후, 빌드 탭을 선택하고 플랫폼을 x86으로 선택하면 된다. 전체 빌드하는 것을 잊지 않도록 한다.

.NET 완전 실망이얌!