【发布时间】:2016-01-24 03:54:53
【问题描述】:
我在尝试通过 DLL 运行函数时遇到了一些麻烦。 执行函数时出现以下错误(编译正常):
无效的类类型转换
代码如下:
#include <fmx.h>
#define CRIPTNSDLL_EXPORTS
#include "CriptLib.h"
#include <FMX.Memo.hpp>
#include <System.Classes.hpp>
#include <string.h>
#pragma hdrstop
#pragma argsused
//---------------------------------------------------------------------------
void Cript_BasicoM (String Original, String Chave, TMemo* Memo){
if (Original.Length() != Chave.Length()) {
throw Exception (L"Não é possível encriptar o conteúdo.\nO tamanho das palaras chave e original não podem ser diferentes.");
}
for (int i = 0; i < Chave.Length(); i++) {
for (int p = 0; p < Chave.Length(); p++) {
if (Chave.c_str()[i] == Chave.c_str()[p] && p != i) {
throw Exception (L"Não é possível encriptar o conteúdo.\nA chave não pode ter dois caracteres iguais.");
}
}
}
for (int i = 0; i < Original.Length(); i++) {
for (int p = 0; p < Original.Length(); p++) {
if (Original.c_str()[i] == Original.c_str()[p] && p != i) {
throw Exception (L"Não é possível encriptar o conteúdo.\nA palavra original não pode ter dois caracteres iguais.");
}
}
}
String Linha = NULL;
Memo->BeginUpdate();
for (int i = 0; i < Original.Length(); i++) {
for (int k = 0; k < Memo->Lines->Count; k++) {
Linha = Memo->Lines->Strings[k];
for (int l = 0; l < Linha.Length(); l++) {
if (Linha.c_str()[l] == Original.c_str()[i]) Linha.c_str()[l] = Chave.c_str() [i];
else if (Linha.c_str()[l] == Chave.c_str()[i]) Linha.c_str()[l] = Original.c_str() [i];
}
Memo->Lines->Strings[k] = Linha;
}
}
Memo->Lines->Add(Original);
Memo->Lines->Add("CriptB");
Memo->EndUpdate();
Memo->Repaint();
}
头文件:
#ifndef CriptLibH
#define CriptLibH
#ifdef CRIPTNSDLL_EXPORTS
#define CRIPTLIB_API __declspec(dllexport)
#else
#define CRIPTLIB_API __declspec(dllimport)
#endif
#ifdef __cplusplus
#include <fmx.h>
#include <FMX.Dialogs.hpp>
#include <System.Classes.hpp>
#include <string.h>
#include <FMX.Memo.hpp>
extern "C" {
#endif
CRIPTLIB_API void Cript_BasicoM(String Original, String Chave, TMemo* Memo);
CRIPTLIB_API void Cript_BasicoL(String Original, String Chave, TStringList* Lista);
CRIPTLIB_API void Cript_BasicoS(String Original, String Chave, String Linha);
CRIPTLIB_API void Decript_BasicoM(String Chave, TMemo* Memo);
CRIPTLIB_API void Decript_BasicoL(String Chave, TStringList* Lista);
CRIPTLIB_API void Decript_BasicoS(String Original, String Chave, String Linha);
CRIPTLIB_API String VerProg();
#ifdef __cplusplus
}
namespace CriptLib
{
class Encriptar
{
public:
static void Subst(String Original, String Chave, TMemo* Memo) { Cript_BasicoM(Original, Chave, Memo); }
static void Subst(String Original, String Chave, TStringList* Lista) { Cript_BasicoL(Original, Chave, Lista); }
static void Subst(String Original, String Chave, String Linha) { Cript_BasicoS(Original, Chave, Linha); }
};
class Decriptar
{
public:
static void Subst(String Chave, TMemo* Memo) { Decript_BasicoM(Chave, Memo); }
static void Subst(String Chave, TStringList* Lista) { Decript_BasicoL(Chave, Lista); }
static void Subst(String Original, String Chave, String Linha) { Decript_BasicoS(Original, Chave, Linha); }
};
class Info
{
public:
static String Ver() { return VerProg(); }
};
}
#endif
#endif
调用函数(也是抛出异常的地方):
CriptLib::Encriptar::Subst(edtOriginal->Text, edtKey->Text, memoContent);
调试器说明:
77303E28 美元的第一次机会例外。异常类 EInvalidCast 与 消息“无效的类类型转换”。处理 Project1.exe (7476)
我找到了问题的确切位置。当使用 Memo->Lines->Count 与 for 结构进行比较时。为了确保我创建了一个整数变量并尝试使用 Count 属性进行均衡化并将其用于 for(甚至像 int(Memo->Lines->Count) 这样的转换)。但是我也得到了错误。 (现在使用调试器)。我坚信它不应该发生,一旦属性 Count 返回一个整数值(我多次使用这个表达式)。
从现在开始,非常感谢。
【问题讨论】:
-
您是否尝试过使用调试器来识别引发异常的位置,如果没有,为什么不呢?
-
它只是显示错误的地址,但我不知道如何识别它。所以,我决定在代码的每一步都放上try块,运行for时抛出异常。
-
发布一个完整但最小的例子,读者可以尝试
-
刚刚添加了编译调试信息,不知道是否真的有帮助
-
跨 DLL 边界传递对象是一个普遍的问题。您必须确保双方使用完全相同的编译器和链接器开关(即 DLL 以及调用 DLL 的代码),并链接到完全相同的运行时库。即使那样,它也可能不起作用。
标签: c++ c++builder firemonkey