문제

그것은 아주 간단합니다.가 있 c++기능을 사용하는 ByRef 매개 변수를 반환하 세 개의 변수를 동일한 시간에.

STDMETHODIMP CReportManager::GetReportAccessRights(long lReportCode, VARIANT_BOOL *bShared, VARIANT_BOOL *bRunOnly, VARIANT_BOOL *bCopy)

그러나,VBScript ASP 코드는 보이지 않을 선택한 새로운 값을 bShares,bRunOnly 및 bCopy 호출할 때는 c++기능입니다.

dim bAllShared, bAllCopy, bAllRunOnly
bAllShared = true
bAllCopy = true
bAllRunOnly = true
m_oReportManager.GetReportAccessRights CLng(m_lRptCod), CBool(bAllShared), CBool(bAllRunOnly), CBool(bAllCopy)
'bAllShared always equals true

거기에 아무것도 할 수 있는 문제를 해결합니까?할 수 있는 사람이 왜 이 작품은 이 방법은?

도움이 되었습니까?

해결책

두 가지 문제가 있습니다:

첫째,검색할 수 없습 값으로 다시 전달 [ref] 에서 매개 변수 VBScript,지 않는 한 그들은 형식 VARIANT 에서는 C++코드입니다.

VBScript 사용하는 늦은-바인딩 기술 COM 자동화하는 경로는 모든 메소드를 호출하 COM 체를 통해 하나의 일반적인 방법을 통: IDISPATCH:Invoke(...).(Visual Basic 동일한 기술을 사용할 때 희미한 변수 As Object 전화를 걸고,그 위에)

Invoke() 는 문자열을 사용하는 메소드의 이름을 부르고 있고의 배열을 매개 변수(기타 재료는 중요하지 않다 여기).

C++개체 걱정하지 않기 때문에 그것에 대해 ATL 지원 듀얼 인터페이스는 모든 불쾌한 당신을 위해 작동합니다.면 개체라는 전화를 받을 IDISPATCH:Invoke(), ATL 니다:

  • 보 요청한 메서드 이름이를 식별하고 해당 클래스의 메소드(그것은 존재하는 경우,그렇지 않으면 그것은 오류가 발생합니다 다시 VBScript).
  • 번역 입력 매개변수를 필요에 따라에서 VARIANT (기술 VARIANTARG, 는 거의 동일)를 적합한 데이터 형식에 따른 방식의 서명(과하면 오류가 발생합니다 그들이 일치하지 않는 어떤 방법을 기대하)
  • 전화 GetReportAccessRights() 방법으로,다음과 같은 조건 매개 변수입니다.

GetReportAccessRights() 메소드가 반환 ATL 다시 패키지 [retval] 새로운 매개 변수 VARIANT (techincally VARIANTARG 고)반환하는 것 VBScript.

지금,당신은 당신 다시 전달 [ref] 값뿐만 아니라,하지만 그들은 VARIANTs.ATL 지 않습 리패키지의 모든 매개 변수 값 이외의 다른 [retval] 당신을 위해,그래서 당신은 당신을 사용해야의 유형 VARIANT *[ref] 인수하려는 돌아갑니다.을 할 때,ATL 이 매개 변수를 방해받지 않고 VBScript 은 그것을 받을 것이 다시습니다.

을 일으로 개 COM 헤더 제공하는 우리와 함께 편의 매크로와 상수,나는 여기서 사용하는(VT_BOOL,V_VT(),V_BOOL(),실패()):

// I usually initialize to Empty at the top of the method,
// before anything can go wrong.
VariantInit(bAllShared);

// My bad -- ignore the above. It applies to [out] parameters only.
// Because bAllShared is passed as a [ref] variable,
// calling VariantInit() on them would leak any preexisting value.
// Instead, read the incoming value from the variable (optional),
// then "clear" them before storing new values (mandatory):

// This API figures out what's in the variable and releases it if needed
// * Do nothing on ints, bools, etc.
// * Call pObj->Release() if an Object
// * Call SysFreeString() if a BSTR
// etc
VariantClear(bAllShared); 

초기화;원인 이전 값을 누수가 발생합니다.

을 읽 VARIANT:

// Always check that the value is of the proper type
if (V_VT(bAllShared) == VT_BOOL ) {
    // good
    bool myArg = (V_BOOL(bAllShared) == VARIANT_TRUE);
} else {
    // error, bad input
}

또는 더 나은,당신은 항상 시도 자신을 변환하기 때문에,VBScript 사용자가 기대하는"True"1 와 동일하게 동작하도록 한다.다행히도,COM 는 멋진 유틸리티에 대한 API 를는:

// This is exactly the same thing that VBScript does internally
// when you call CBool(...)
VARIANT v;
VariantInit(&v);
if( FAILED(VariantChangeType(&v, &bAllShared, 0, VT_BOOL) )
{
    // error, can't convert
} 
bool myArg = (V_BOOL(v) == VARIANT_TRUE);

VARIANT:

// Internal working value
bool isShared;
...

// set the Variant's type to VARIANT_BOOL
V_VT(bAllShared)   = VT_BOOL;

// set the value
V_BOOL(bAllShared) = (isShared ? VARIANT_TRUE : VARIANT_FALSE);

지금,두 번째 문제는 샘플에 VBScript 코드:

m_oReportManager.GetReportAccessRights _
    CLng(m_lRptCod), CBool(bAllShared), CBool(bAllRunOnly), CBool(bAllCopy)

기 때문에 당신은 당신을 인수로 전달하는 CBool(something), 등,당신은 다시 전달 변수 임시(의 반환 값 CBool(...)),실제변수 bAllShared, 니다,등등.을 정도로 정확한 C++구현을 반환된 값으로 폐기 중간 값입니다.

당신을 부를 필요가 방법은 다음과 같다:

m_oReportManager.GetReportAccessRights _
    CLng(m_lRptCod), bAllShared, bAllRunOnly, bAllCopy

그렇습니다.당신이 필요하지 않"변환"이 값이 있습니다.VBScript 은 항상 전달 VARIANT 상관없이 당신이 무엇을 할 것입니다.걱정하지 마세요,제가 말했듯 위,심지어를 입력 매개변수의 유형 bool,etc.,ATL 을 만들 것입 통화 CBool() 습니다.

(ATL 전화 CBool()?지 않는 VBScript 기능입니까? 네,하지만 CBool()간단한 래퍼 VariantChangeType(), 는 무슨 ATL 합니다)

편집: 내가 잊을 언급하는 다른 무언가:VBScript 지원하지 않는 [out] 매개 변수만 [ref] 매개 변수입니다.지 않으로 매개 변수를 선언 [out] 에서는 C++.는 경우에 당신의 방법을 선언 [out] 매개변수,VBScript 것처럼 행동들 [ref] 매개 변수입니다.를 일으키는 원인이 될 것이다 들어오는 값의 매개 변수가 유출.는 경우 하나의[out]인수했다 원래 문자열에는 메모리 누출;는 경우 그 개체는 개체는 결코 무너지지 않을 것이다.

다른 팁

이 경우에 구현 된 또 다른 어리석은 솔루션은 VB6을 사용하여 C ++ 함수 호출을 마무리하고 3 개의 참조 변수를 VB6 COM 객체의 함수로 제공하는 것이 었습니다.

Option Explicit
Private bSharedaccess As Boolean
Private bRunOnlyaccess As Boolean
Private bCopyaccess As Boolean

Public Sub Initialize(ByVal oSession As Starbridge.Session, ByVal lReportID As Long)

    bSharedaccess = True
    bRunOnlyaccess = False
    bCopyaccess = True
    Call oSession.ReportManager.GetReportAccessRights(lReportID, bSharedaccess, bRunOnlyaccess, bCopyaccess)

End Sub

Public Function GetSharedAccess()
    GetSharedAccess = bSharedaccess
End Function

Public Function GetRunOnlyAccess()
    GetRunOnlyAccess = bRunOnlyaccess
End Function

Public Function GetCopyAccess()
    GetCopyAccess = bCopyaccess
End Function
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top