programing

런타임 오류 49, 잘못된 DLL 호출 규칙

mailnote 2023. 11. 2. 22:01
반응형

런타임 오류 49, 잘못된 DLL 호출 규칙

Q. Excel은 내 애드인이 로드될 때마다 다음 오류를 계속 던집니다(Runtime Error 49, Bad DLL 호출 규칙).

Error

외부 DLL 참조가 전혀 없음에도 불구하고 오류 위치를 표시하지 않고 대화상자가 항상 팝업되기 시작합니다.

오어

Q. 특정 라인의 코드를 저장할 때마다 Excel이 크래시됩니다.

어떻게 고칠 수 있습니까?

이 오류는 컴파일러 버그 때문에 발생한 것일 수 있습니다.이에 대한 가장 쉬운 해결책은 작은 코드 변경을 하고 다시 컴파일하는 것입니다.제가 주로 하는 일은.

1 -> 추가Private Enum추가의 모듈 상단에 입력합니다.

Private Enum Something
    member = 1
End Enum

2 -> addin 컴파일

3 -> Excel 재시작

4 -> 변경된 코드를 제거합니다.그것은 더 이상 필요하지 않습니다.

  1. 이 오류는 DLL(외부) 함수 호출을 의미하더라도 VBA 정의 함수 또는 서브루틴에 대한 매개 변수 또는 반환 값 유형 불일치로 인해 트리거될 수 있습니다.또한 이러한 원인으로 인해 디버거가 트리거되면 문제 상황이 생성될 때까지 작동하고 안정적이었던 호출을 포함하여 종종 호출 스택에서 오류 지점이 다른 함수 호출로 표시됩니다.종종 문제는 고정형 매개 변수 인수 또는 반환 값과 변형 또는 그 반대의 값 사이의 불일치로 인해 트리거됩니다.

    예: 변형 값 함수는 정수 변수에 할당된 런타임에 Long 값을 반환합니다.

    해상도:

    • 특히 최근에 작업한 루틴의 경우 모든 매개 변수 인수 및 반환 값 유형과 할당 문을 주의 깊게 확인합니다.변형 값 함수가 있는 경우 할당에 대한 올바른 유형으로 명시적으로 입력합니다.
    • Application 사용으로 인해 위와 같은 상황이 불가피한 경우.Application의 결과로 다른 워크북(파라미터 정의에 대한 제어권이 없는 경우)에서 루틴을 호출하는 메서드를 실행합니다.method passing all 인수 ByVal을 실행한 다음 포함 루틴이 Sub인 경우 반환 유형이 지정되지 않은 함수로 변환해 봅니다.이는 스택을 강제로 정리하고 콜 스택에서 상위 레벨로 오류 조건이 던져지는 것을 억제하는 것으로 보입니다.
  2. 이 메서드를 사용할 수 없는 잘못된 개체 변형에 적용되는 개체 메서드(예: AutoFit이 전체 행 또는 전체 열 범위가 아닌 범위에 적용되는 경우)입니다.위 시나리오와 유사하게 오류는 문제 문 자체가 아닌 문제 문이 존재하는 루틴의 반환 지점에 던져질 수 있습니다.

    해상도:구문 문제 해결부터 시작합니다.불행하게도 작동해야 하는 수정은 때때로 VBE 편집기가 재설정될 때까지 오류를 계속 발생시킵니다.이 문제를 해결할 수 있는 최소한의 단계를 도출하지는 못했지만 종종 이와 같은 방법이 적용됩니다.

    • 프로젝트를 명시적으로 다시 컴파일합니다.
    • 파일을 저장하고 닫습니다.
    • 파일을 다시 열고 코드를 다시 실행합니다.
  3. 외부 라이브러리 함수에 대한 호출이 원인으로 확인되면 Microsoft의 오류 설명서를 참조하십시오.

    DLL 호출 규칙이 잘못되었습니다.

    *다이나믹 링크 라이브러리(DLL)로 전달되는 인수는 루틴에서 예상하는 인수와 정확히 일치해야 합니다.호출 규칙은 인수의 번호, 유형 및 순서를 다룹니다.DLL에서 잘못된 형식이나 인수 개수를 전달하는 루틴을 프로그램에서 호출하고 있을 수 있습니다.

    이 오류를 수정하려면 모든 인수 유형이 호출 중인 루틴의 선언에 지정된 것과 일치해야 합니다.

    호출하는 루틴의 선언에 표시된 것과 동일한 수의 인수를 전달하고 있는지 확인합니다.

    DLL 루틴에서 값별 인수를 예상하는 경우 루틴에 대한 선언에서 해당 인수에 대해 ByVal이 지정되었는지 확인합니다.

    반환 인수:절차 논변을 이야기할 때 쉽게 간과할 수 있는 한 가지는 반환 논변입니다.유형이 올바른지 또는 누락되지 않았는지 확인합니다.Excel/VBA 사용자는 함수의 반환 유형을 생략하면 시스템이 반환 유형을 변형으로 암묵적으로 설정하고 반환된 데이터와 함께 작동한다는 사실에 익숙합니다.외부에서 신고된 기능은 그렇지 않습니다!!반환 유형은 DELECORE 문에 선언해야 합니다.*

  4. 깨진 라이브러리 참조: 모듈 코드에 대한 라이브러리 참조가 올바른지 확인합니다.VBA IDE에서 Tools=> References(도구".> 참조)를 선택하여 참조된 라이브러리 목록을 보고 선택한 항목 중 "Missing(실종)"으로 표시된 항목이 없는지 확인합니다.그렇다면 고쳐주세요.

아니면, 최고의 옵션:

- 루틴의 이름을 다시 씁니다.

- 그럼 재컴파일!

이제 가셔도 좋습니다!

참고로 엑셀 VBA 코드에서 잘 실행되던 "Runtime Error 49, Bad DLL calling convention"도 경험했습니다.

오류는 내부 함수 호출을 가리키고 있었고 수정은 인수를 ByVal에서 ByRef로 변경하는 것이었습니다.해당 값이 이미 ByRef로 전달된 다른 함수에 대한 호출이 있었으므로 이것이 요인이 되었을 수 있습니다.

"변경/추가 및 재컴파일" 대신 프로젝트를 /컴파일 해제하는 방법도 있습니다.특히 많은 문제를 해결할 수 있는 대규모 액세스/엑셀 프로젝트에서.

다른 가능한 원인을 추가하기 위해서, 는 애플리케이션을 사용하고 있습니다.매개 변수가 있는 공개 서브를 호출하는 OnTime 메서드입니다.매개 변수는 긴(현재 행)을 의미하지만 실제로는 문자열 값으로 전달된 것으로 추측됩니다.

다음은 OnTime 호출의 예입니다.

Application.OnTime Now + TimeValue("00:00:01"), "'UpdateEditedPref " & curRow & "'"

코드를 임의로 업데이트하고 다시 컴파일하려고 했지만 이 문제는 해결되지 않았습니다.이것이 수정한 것은 매개변수 유형을 호출된 서브에서 긴 것에서 문자열로 변경하는 것이었습니다.

Public Sub UpdateEditedPref(ByVal inRowStr As String)

그러면 문자열을 서브 내의 값으로 변환하면 됩니다.다행히도 더 이상의 실수는 없습니다.

업데이트: Application을 사용하여 매개 변수를 전달합니다.OnTime이 "매크로를 실행할 수 없습니다"라는 또 다른 오류를 발생시킨 것 같습니다.워크시트가 잠겨 있을 때 이 오류가 발생했습니다.저는 아직 Application을 사용하고 있습니다.OnTime, 그러나 매개 변수를 전달하는 대신 글로벌 변수에 값을 저장하고 호출된 서브에 해당 값을 사용합니다.이제 올바르게 작동하는 것 같습니다.

이제 OnTime 통화는 다음과 같습니다.

' Set global variable
gCurRow = curRow

Application.OnTime Now + TimeValue("00:00:01"), "UpdateEditedPref"

저도 비슷한 문제가 있었는데, 제 개발 PC에서는 잘 작동하고 있었습니다.재미있는 것은 같은 루틴에 두 번의 전화가 있었는데, 한 번은 작동하고 다른 한 번은 작동하지 않았다는 것입니다.프로덕션 PC에서 계속 오류가 발생했습니다.루틴의 이름을 바꾸고 매개 변수, 매개 변수 유형을 변경하려고 했지만 사용할 수 없었습니다.

저에게 효과가 있었던 것은 실패한 호출 루틴을 호출된 서브루틴과 동일한 모듈로 이동시키는 것이었습니다.

이전에 작동하던 루틴이 이미 동일한 모듈에 있었습니다.

제 경우에는 조건부인 경우 하나로 계속 문자를 과도하게 사용하여 "원인"이 되었습니다.

나는 이미 다시 컴파일을 했고, 모든 반품 코드를 확인했고, 모듈을 이리저리 옮기고, 엑셀을 다시 시작했고, 내 컴퓨터를 다시 시작했고, 그 코드를 새로운 엑셀 스프레드시트에 복사했습니다. 나는 이 기사를 읽었고 반품 코드에 대한 부분은 if문에 얼마나 많은 반품이 있을 수 있는지 생각하게 했습니다.

나 이거 먹었어요.

    If CompressIntoOneLineON(rg1, rgstart, rgend) or _
       CompressIntoOneLineOS(rg1, rgstart, rgend) or _
       CompressIntoOneLineOGN(rg1, rgstart, rgend) or _
       CompressIntoOneLineOGS(rg1, rgstart, rgend) or _
       CompressIntoOneLineGO(rg1, rgstart, rgend) Then
       <code>
    End If

이 코드가 포함된 서브루틴이 종료되었을 때 오류가 발생했습니다. 그래서 이 코드로 변경했습니다.

matched = True
If CompressIntoOneLineON(rg1, rgstart, rgend) Then
ElseIf CompressIntoOneLineOS(rg1, rgstart, rgend) Then
ElseIf CompressIntoOneLineOGN(rg1, rgstart, rgend) Then
ElseIf CompressIntoOneLineOGS(rg1, rgstart, rgend) Then
ElseIf CompressIntoOneLineGO(rg1, rgstart, rgend) Then
Else
  matched = False
End If
if matched then
  <code>

그리고 오류는 사라졌습니다.

실험 결과 다음과 같이 나타났습니다.선언을 바꾸자 'Runtime Error 49, Bad DLL 호출 규약'이라는 오류가 사라졌습니다.

Dim coll as new Collection

위에

Dim coll as Collection
Set coll = New Collection

개체의 존재를 추적할 수 있도록 개체가 생성 실패 시 Nothing on failure(Nothing on failure)(자체가 아닌 경우)로 명시적으로 되어야 합니다.

감사합니다, 러버덕 VBA.

언급URL : https://stackoverflow.com/questions/15758834/runtime-error-49-bad-dll-calling-convention

반응형